LCOV - code coverage report
Current view: top level - js/src/frontend - Parser.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 1282 3983 32.2 %
Date: 2018-08-07 16:42:27 Functions: 0 0 -
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             : /*
       8             :  * JS parser.
       9             :  *
      10             :  * This is a recursive-descent parser for the JavaScript language specified by
      11             :  * "The ECMAScript Language Specification" (Standard ECMA-262).  It uses
      12             :  * lexical and semantic feedback to disambiguate non-LL(1) structures.  It
      13             :  * generates trees of nodes induced by the recursive parsing (not precise
      14             :  * syntax trees, see Parser.h).  After tree construction, it rewrites trees to
      15             :  * fold constants and evaluate compile-time expressions.
      16             :  *
      17             :  * This parser attempts no error recovery.
      18             :  */
      19             : 
      20             : #include "frontend/Parser.h"
      21             : 
      22             : #include "mozilla/Range.h"
      23             : #include "mozilla/Sprintf.h"
      24             : #include "mozilla/TypeTraits.h"
      25             : 
      26             : #include <memory>
      27             : #include <new>
      28             : 
      29             : #include "jsapi.h"
      30             : #include "jstypes.h"
      31             : 
      32             : #include "builtin/ModuleObject.h"
      33             : #include "builtin/SelfHostingDefines.h"
      34             : #include "frontend/BytecodeCompiler.h"
      35             : #include "frontend/FoldConstants.h"
      36             : #include "frontend/TokenStream.h"
      37             : #include "irregexp/RegExpParser.h"
      38             : #include "vm/BytecodeUtil.h"
      39             : #include "vm/JSAtom.h"
      40             : #include "vm/JSContext.h"
      41             : #include "vm/JSFunction.h"
      42             : #include "vm/JSScript.h"
      43             : #include "vm/RegExpObject.h"
      44             : #include "vm/StringType.h"
      45             : #include "wasm/AsmJS.h"
      46             : 
      47             : #include "frontend/ParseContext-inl.h"
      48             : #include "frontend/ParseNode-inl.h"
      49             : #include "vm/EnvironmentObject-inl.h"
      50             : #include "vm/JSAtom-inl.h"
      51             : #include "vm/JSScript-inl.h"
      52             : 
      53             : using namespace js;
      54             : using namespace js::gc;
      55             : 
      56             : using mozilla::Maybe;
      57             : using mozilla::Nothing;
      58             : using mozilla::PodCopy;
      59             : using mozilla::PodZero;
      60             : using mozilla::Some;
      61             : 
      62             : using JS::AutoGCRooter;
      63             : 
      64             : namespace js {
      65             : namespace frontend {
      66             : 
      67             : using DeclaredNamePtr = ParseContext::Scope::DeclaredNamePtr;
      68             : using AddDeclaredNamePtr = ParseContext::Scope::AddDeclaredNamePtr;
      69             : using BindingIter = ParseContext::Scope::BindingIter;
      70             : using UsedNamePtr = UsedNameTracker::UsedNameMap::Ptr;
      71             : 
      72             : // Read a token. Report an error and return null() if that token doesn't match
      73             : // to the condition.  Do not use MUST_MATCH_TOKEN_INTERNAL directly.
      74             : #define MUST_MATCH_TOKEN_INTERNAL(cond, modifier, errorReport)                              \
      75             :     JS_BEGIN_MACRO                                                                          \
      76             :         TokenKind token;                                                                    \
      77             :         if (!tokenStream.getToken(&token, modifier))                                        \
      78             :             return null();                                                                  \
      79             :         if (!(cond)) {                                                                      \
      80             :             errorReport;                                                                    \
      81             :             return null();                                                                  \
      82             :         }                                                                                   \
      83             :     JS_END_MACRO
      84             : 
      85             : #define MUST_MATCH_TOKEN_MOD(tt, modifier, errorNumber) \
      86             :     MUST_MATCH_TOKEN_INTERNAL(token == tt, modifier, error(errorNumber))
      87             : 
      88             : #define MUST_MATCH_TOKEN(tt, errorNumber) \
      89             :     MUST_MATCH_TOKEN_MOD(tt, TokenStream::None, errorNumber)
      90             : 
      91             : #define MUST_MATCH_TOKEN_FUNC_MOD(func, modifier, errorNumber) \
      92             :     MUST_MATCH_TOKEN_INTERNAL((func)(token), modifier, error(errorNumber))
      93             : 
      94             : #define MUST_MATCH_TOKEN_FUNC(func, errorNumber) \
      95             :     MUST_MATCH_TOKEN_FUNC_MOD(func, TokenStream::None, errorNumber)
      96             : 
      97             : #define MUST_MATCH_TOKEN_MOD_WITH_REPORT(tt, modifier, errorReport) \
      98             :     MUST_MATCH_TOKEN_INTERNAL(token == tt, modifier, errorReport)
      99             : 
     100             : template <class T, class U>
     101           0 : static inline void
     102             : PropagateTransitiveParseFlags(const T* inner, U* outer)
     103           0 : {
     104             :     if (inner->bindingsAccessedDynamically())
     105           0 :         outer->setBindingsAccessedDynamically();
     106             :     if (inner->hasDebuggerStatement())
     107           0 :         outer->setHasDebuggerStatement();
     108             :     if (inner->hasDirectEval())
     109           0 :         outer->setHasDirectEval();
     110             : }
     111             : 
     112           0 : static const char*
     113             : DeclarationKindString(DeclarationKind kind)
     114           0 : {
     115             :     switch (kind) {
     116             :       case DeclarationKind::PositionalFormalParameter:
     117             :       case DeclarationKind::FormalParameter:
     118             :         return "formal parameter";
     119           0 :       case DeclarationKind::CoverArrowParameter:
     120             :         return "cover arrow parameter";
     121           0 :       case DeclarationKind::Var:
     122             :         return "var";
     123           0 :       case DeclarationKind::Let:
     124             :         return "let";
     125           0 :       case DeclarationKind::Const:
     126             :         return "const";
     127           0 :       case DeclarationKind::Class:
     128             :         return "class";
     129           0 :       case DeclarationKind::Import:
     130             :         return "import";
     131             :       case DeclarationKind::BodyLevelFunction:
     132             :       case DeclarationKind::ModuleBodyLevelFunction:
     133             :       case DeclarationKind::LexicalFunction:
     134           0 :       case DeclarationKind::SloppyLexicalFunction:
     135             :         return "function";
     136           0 :       case DeclarationKind::VarForAnnexBLexicalFunction:
     137             :         return "annex b var";
     138           0 :       case DeclarationKind::ForOfVar:
     139             :         return "var in for-of";
     140             :       case DeclarationKind::SimpleCatchParameter:
     141           0 :       case DeclarationKind::CatchParameter:
     142             :         return "catch parameter";
     143             :     }
     144           0 : 
     145             :     MOZ_CRASH("Bad DeclarationKind");
     146             : }
     147             : 
     148             : static bool
     149             : StatementKindIsBraced(StatementKind kind)
     150           0 : {
     151           0 :     return kind == StatementKind::Block ||
     152           0 :            kind == StatementKind::Switch ||
     153             :            kind == StatementKind::Try ||
     154           0 :            kind == StatementKind::Catch ||
     155           0 :            kind == StatementKind::Finally ||
     156             :            kind == StatementKind::Class;
     157             : }
     158             : 
     159           0 : void
     160             : ParseContext::Scope::dump(ParseContext* pc)
     161           0 : {
     162             :     JSContext* cx = pc->sc()->context;
     163           0 : 
     164             :     fprintf(stdout, "ParseScope %p", this);
     165           0 : 
     166           0 :     fprintf(stdout, "\n  decls:\n");
     167           0 :     for (DeclaredNameMap::Range r = declared_->all(); !r.empty(); r.popFront()) {
     168           0 :         JSAutoByteString bytes;
     169           0 :         if (!AtomToPrintableString(cx, r.front().key(), &bytes))
     170           0 :             return;
     171           0 :         DeclaredNameInfo& info = r.front().value().wrapped;
     172             :         fprintf(stdout, "    %s %s%s\n",
     173             :                 DeclarationKindString(info.kind()),
     174           0 :                 bytes.ptr(),
     175             :                 info.closedOver() ? " (closed over)" : "");
     176             :     }
     177           0 : 
     178             :     fprintf(stdout, "\n");
     179             : }
     180             : 
     181           0 : bool
     182             : ParseContext::Scope::addPossibleAnnexBFunctionBox(ParseContext* pc, FunctionBox* funbox)
     183           0 : {
     184           0 :     if (!possibleAnnexBFunctionBoxes_) {
     185             :         if (!possibleAnnexBFunctionBoxes_.acquire(pc->sc()->context))
     186             :             return false;
     187             :     }
     188           0 : 
     189             :     return possibleAnnexBFunctionBoxes_->append(funbox);
     190             : }
     191             : 
     192           0 : bool
     193             : ParseContext::Scope::propagateAndMarkAnnexBFunctionBoxes(ParseContext* pc)
     194             : {
     195           0 :     // Strict mode doesn't have wack Annex B function semantics.
     196           0 :     if (pc->sc()->strict() ||
     197           0 :         !possibleAnnexBFunctionBoxes_ ||
     198             :         possibleAnnexBFunctionBoxes_->empty())
     199             :     {
     200             :         return true;
     201             :     }
     202           0 : 
     203             :     if (this == &pc->varScope()) {
     204             :         // Base case: actually declare the Annex B vars and mark applicable
     205           0 :         // function boxes as Annex B.
     206           0 :         RootedPropertyName name(pc->sc()->context);
     207             :         Maybe<DeclarationKind> redeclaredKind;
     208           0 :         uint32_t unused;
     209           0 :         for (FunctionBox* funbox : *possibleAnnexBFunctionBoxes_) {
     210           0 :             if (pc->annexBAppliesToLexicalFunctionInInnermostScope(funbox)) {
     211           0 :                 name = funbox->function()->explicitName()->asPropertyName();
     212             :                 if (!pc->tryDeclareVar(name,
     213             :                                        DeclarationKind::VarForAnnexBLexicalFunction,
     214             :                                        DeclaredNameInfo::npos, &redeclaredKind, &unused))
     215           0 :                 {
     216             :                     return false;
     217             :                 }
     218           0 : 
     219           0 :                 MOZ_ASSERT(!redeclaredKind);
     220             :                 funbox->isAnnexB = true;
     221             :             }
     222             :         }
     223             :     } else {
     224             :         // Inner scope case: propagate still applicable function boxes to the
     225           0 :         // enclosing scope.
     226           0 :         for (FunctionBox* funbox : *possibleAnnexBFunctionBoxes_) {
     227           0 :             if (pc->annexBAppliesToLexicalFunctionInInnermostScope(funbox)) {
     228             :                 if (!enclosing()->addPossibleAnnexBFunctionBox(pc, funbox))
     229             :                     return false;
     230             :             }
     231             :         }
     232             :     }
     233             : 
     234             :     return true;
     235             : }
     236             : 
     237             : static bool
     238             : DeclarationKindIsCatchParameter(DeclarationKind kind)
     239           0 : {
     240             :     return kind == DeclarationKind::SimpleCatchParameter ||
     241             :            kind == DeclarationKind::CatchParameter;
     242             : }
     243             : 
     244           0 : bool
     245             : ParseContext::Scope::addCatchParameters(ParseContext* pc, Scope& catchParamScope)
     246           0 : {
     247             :     if (pc->useAsmOrInsideUseAsm())
     248             :         return true;
     249           0 : 
     250           0 :     for (DeclaredNameMap::Range r = catchParamScope.declared_->all(); !r.empty(); r.popFront()) {
     251           0 :         DeclarationKind kind = r.front().value()->kind();
     252           0 :         uint32_t pos = r.front().value()->pos();
     253           0 :         MOZ_ASSERT(DeclarationKindIsCatchParameter(kind));
     254           0 :         JSAtom* name = r.front().key();
     255           0 :         AddDeclaredNamePtr p = lookupDeclaredNameForAdd(name);
     256           0 :         MOZ_ASSERT(!p);
     257           0 :         if (!addDeclaredName(pc, p, name, kind, pos))
     258             :             return false;
     259             :     }
     260           0 : 
     261             :     return true;
     262             : }
     263             : 
     264           0 : void
     265             : ParseContext::Scope::removeCatchParameters(ParseContext* pc, Scope& catchParamScope)
     266           0 : {
     267             :     if (pc->useAsmOrInsideUseAsm())
     268             :         return;
     269           0 : 
     270           0 :     for (DeclaredNameMap::Range r = catchParamScope.declared_->all(); !r.empty(); r.popFront()) {
     271           0 :         DeclaredNamePtr p = declared_->lookup(r.front().key());
     272             :         MOZ_ASSERT(p);
     273             : 
     274             :         // This check is needed because the catch body could have declared
     275           0 :         // vars, which would have been added to catchParamScope.
     276           0 :         if (DeclarationKindIsCatchParameter(r.front().value()->kind()))
     277             :             declared_->remove(p);
     278             :     }
     279             : }
     280             : 
     281           0 : void
     282             : SharedContext::computeAllowSyntax(Scope* scope)
     283           0 : {
     284           0 :     for (ScopeIter si(scope); si; si++) {
     285           0 :         if (si.kind() == ScopeKind::Function) {
     286           0 :             JSFunction* fun = si.scope()->as<FunctionScope>().canonicalFunction();
     287             :             if (fun->isArrow())
     288           0 :                 continue;
     289           0 :             allowNewTarget_ = true;
     290           0 :             allowSuperProperty_ = fun->allowSuperProperty();
     291           0 :             allowSuperCall_ = fun->isDerivedClassConstructor();
     292             :             return;
     293             :         }
     294             :     }
     295             : }
     296             : 
     297           0 : void
     298             : SharedContext::computeThisBinding(Scope* scope)
     299           0 : {
     300           0 :     for (ScopeIter si(scope); si; si++) {
     301           0 :         if (si.kind() == ScopeKind::Module) {
     302           0 :             thisBinding_ = ThisBinding::Module;
     303             :             return;
     304             :         }
     305           0 : 
     306           0 :         if (si.kind() == ScopeKind::Function) {
     307             :             JSFunction* fun = si.scope()->as<FunctionScope>().canonicalFunction();
     308             : 
     309           0 :             // Arrow functions don't have their own `this` binding.
     310             :             if (fun->isArrow())
     311             :                 continue;
     312             : 
     313             :             // Derived class constructors (including nested arrow functions and
     314           0 :             // eval) need TDZ checks when accessing |this|.
     315           0 :             if (fun->isDerivedClassConstructor())
     316             :                 needsThisTDZChecks_ = true;
     317           0 : 
     318           0 :             thisBinding_ = ThisBinding::Function;
     319             :             return;
     320             :         }
     321             :     }
     322           0 : 
     323             :     thisBinding_ = ThisBinding::Global;
     324             : }
     325             : 
     326           0 : void
     327             : SharedContext::computeInWith(Scope* scope)
     328           0 : {
     329           0 :     for (ScopeIter si(scope); si; si++) {
     330           0 :         if (si.kind() == ScopeKind::With) {
     331           0 :             inWith_ = true;
     332             :             break;
     333             :         }
     334           0 :     }
     335             : }
     336           0 : 
     337             : EvalSharedContext::EvalSharedContext(JSContext* cx, JSObject* enclosingEnv,
     338           0 :                                      Scope* enclosingScope, Directives directives,
     339             :                                      bool extraWarnings)
     340             :   : SharedContext(cx, Kind::Eval, directives, extraWarnings),
     341           0 :     enclosingScope_(cx, enclosingScope),
     342             :     bindings(cx)
     343           0 : {
     344           0 :     computeAllowSyntax(enclosingScope);
     345           0 :     computeInWith(enclosingScope);
     346             :     computeThisBinding(enclosingScope);
     347             : 
     348             :     // If this eval is in response to Debugger.Frame.eval, we may have been
     349             :     // passed an incomplete scope chain. In order to better determine the 'this'
     350             :     // binding type, we traverse the environment chain, looking for a CallObject
     351             :     // and recompute the binding type based on its body scope.
     352             :     //
     353             :     // NOTE: A non-debug eval in a non-syntactic environment will also trigger
     354           0 :     // this code. In that case, we should still compute the same binding type.
     355             :     if (enclosingEnv && enclosingScope->hasOnChain(ScopeKind::NonSyntactic)) {
     356           0 :         JSObject* env = enclosingEnv;
     357             :         while (env) {
     358             :             // Look at target of any DebugEnvironmentProxy, but be sure to use
     359           0 :             // enclosingEnvironment() of the proxy itself.
     360           0 :             JSObject* unwrapped = env;
     361           0 :             if (env->is<DebugEnvironmentProxy>())
     362             :                 unwrapped = &env->as<DebugEnvironmentProxy>().environment();
     363           0 : 
     364           0 :             if (unwrapped->is<CallObject>()) {
     365           0 :                 JSFunction* callee = &unwrapped->as<CallObject>().callee();
     366           0 :                 computeThisBinding(callee->nonLazyScript()->bodyScope());
     367             :                 break;
     368             :             }
     369           0 : 
     370             :             env = env->enclosingEnvironment();
     371             :         }
     372           0 :     }
     373             : }
     374             : 
     375           0 : bool
     376             : ParseContext::init()
     377           0 : {
     378           0 :     if (scriptId_ == UINT32_MAX) {
     379           0 :         errorReporter_.reportErrorNoOffset(JSMSG_NEED_DIET, js_script_str);
     380             :         return false;
     381             :     }
     382           0 : 
     383             :     JSContext* cx = sc()->context;
     384           0 : 
     385             :     if (isFunctionBox()) {
     386             :         // Named lambdas always need a binding for their own name. If this
     387             :         // binding is closed over when we finish parsing the function in
     388             :         // finishExtraFunctionScopes, the function box needs to be marked as
     389           0 :         // needing a dynamic DeclEnv object.
     390           0 :         RootedFunction fun(cx, functionBox()->function());
     391           0 :         if (fun->isNamedLambda()) {
     392           0 :             if (!namedLambdaScope_->init(this))
     393             :                 return false;
     394           0 :             AddDeclaredNamePtr p =
     395           0 :                 namedLambdaScope_->lookupDeclaredNameForAdd(fun->explicitName());
     396           0 :             MOZ_ASSERT(!p);
     397             :             if (!namedLambdaScope_->addDeclaredName(this, p, fun->explicitName(),
     398             :                                                     DeclarationKind::Const,
     399             :                                                     DeclaredNameInfo::npos))
     400             :             {
     401             :                 return false;
     402             :             }
     403             :         }
     404           0 : 
     405             :         if (!functionScope_->init(this))
     406             :             return false;
     407           0 : 
     408             :         if (!positionalFormalParameterNames_.acquire(cx))
     409             :             return false;
     410             :     }
     411           0 : 
     412             :     if (!closedOverBindingsForLazy_.acquire(cx))
     413             :         return false;
     414           0 : 
     415             :     return true;
     416             : }
     417             : 
     418           0 : bool
     419             : UsedNameTracker::noteUse(JSContext* cx, JSAtom* name, uint32_t scriptId, uint32_t scopeId)
     420           0 : {
     421           0 :     if (UsedNameMap::AddPtr p = map_.lookupForAdd(name)) {
     422           0 :         if (!p->value().noteUsedInScope(scriptId, scopeId))
     423             :             return false;
     424           0 :     } else {
     425           0 :         UsedNameInfo info(cx);
     426           0 :         if (!info.noteUsedInScope(scriptId, scopeId))
     427           0 :             return false;
     428             :         if (!map_.add(p, name, std::move(info)))
     429             :             return false;
     430             :     }
     431           0 : 
     432             :     return true;
     433             : }
     434             : 
     435           0 : void
     436             : UsedNameTracker::UsedNameInfo::resetToScope(uint32_t scriptId, uint32_t scopeId)
     437           0 : {
     438           0 :     while (!uses_.empty()) {
     439           0 :         Use& innermost = uses_.back();
     440             :         if (innermost.scopeId < scopeId)
     441           0 :             break;
     442           0 :         MOZ_ASSERT(innermost.scriptId >= scriptId);
     443             :         uses_.popBack();
     444           0 :     }
     445             : }
     446             : 
     447           0 : void
     448             : UsedNameTracker::rewind(RewindToken token)
     449           0 : {
     450           0 :     scriptCounter_ = token.scriptId;
     451             :     scopeCounter_ = token.scopeId;
     452           0 : 
     453           0 :     for (UsedNameMap::Range r = map_.all(); !r.empty(); r.popFront())
     454           0 :         r.front().value().resetToScope(token.scriptId, token.scopeId);
     455             : }
     456           0 : 
     457             : FunctionBox::FunctionBox(JSContext* cx, ObjectBox* traceListHead,
     458             :                          JSFunction* fun, uint32_t toStringStart,
     459           0 :                          Directives directives, bool extraWarnings,
     460             :                          GeneratorKind generatorKind, FunctionAsyncKind asyncKind)
     461             :   : ObjectBox(fun, traceListHead),
     462             :     SharedContext(cx, Kind::FunctionBox, directives, extraWarnings),
     463             :     enclosingScope_(nullptr),
     464             :     namedLambdaBindings_(nullptr),
     465             :     functionScopeBindings_(nullptr),
     466             :     extraVarScopeBindings_(nullptr),
     467             :     functionNode(nullptr),
     468             :     bufStart(0),
     469             :     bufEnd(0),
     470             :     startLine(1),
     471             :     startColumn(0),
     472             :     toStringStart(toStringStart),
     473             :     toStringEnd(0),
     474             :     length(0),
     475             :     isGenerator_(generatorKind == GeneratorKind::Generator),
     476             :     isAsync_(asyncKind == FunctionAsyncKind::AsyncFunction),
     477             :     hasDestructuringArgs(false),
     478             :     hasParameterExprs(false),
     479             :     hasDirectEvalInParameterExpr(false),
     480             :     hasDuplicateParameters(false),
     481             :     useAsm(false),
     482             :     isAnnexB(false),
     483             :     wasEmitted(false),
     484             :     declaredArguments(false),
     485             :     usesArguments(false),
     486             :     usesApply(false),
     487             :     usesThis(false),
     488             :     usesReturn(false),
     489             :     hasRest_(false),
     490             :     hasExprBody_(false),
     491             :     hasExtensibleScope_(false),
     492             :     argumentsHasLocalBinding_(false),
     493             :     definitelyNeedsArgsObj_(false),
     494             :     needsHomeObject_(false),
     495             :     isDerivedClassConstructor_(false),
     496           0 :     hasThisBinding_(false),
     497             :     hasInnerFunctions_(false)
     498             : {
     499             :     // Functions created at parse time may be set singleton after parsing and
     500             :     // baked into JIT code, so they must be allocated tenured. They are held by
     501           0 :     // the JSScript so cannot be collected during a minor GC anyway.
     502           0 :     MOZ_ASSERT(fun->isTenured());
     503             : }
     504             : 
     505           0 : void
     506             : FunctionBox::initFromLazyFunction()
     507           0 : {
     508           0 :     JSFunction* fun = function();
     509           0 :     if (fun->lazyScript()->isDerivedClassConstructor())
     510           0 :         setDerivedClassConstructor();
     511           0 :     if (fun->lazyScript()->needsHomeObject())
     512           0 :         setNeedsHomeObject();
     513           0 :     enclosingScope_ = fun->lazyScript()->enclosingScope();
     514           0 :     initWithEnclosingScope(enclosingScope_);
     515             : }
     516             : 
     517           0 : void
     518             : FunctionBox::initStandaloneFunction(Scope* enclosingScope)
     519             : {
     520             :     // Standalone functions are Function or Generator constructors and are
     521           0 :     // always scoped to the global.
     522           0 :     MOZ_ASSERT(enclosingScope->is<GlobalScope>());
     523           0 :     enclosingScope_ = enclosingScope;
     524           0 :     allowNewTarget_ = true;
     525           0 :     thisBinding_ = ThisBinding::Function;
     526             : }
     527             : 
     528           0 : void
     529             : FunctionBox::initWithEnclosingParseContext(ParseContext* enclosing, FunctionSyntaxKind kind)
     530           0 : {
     531           0 :     SharedContext* sc = enclosing->sc();
     532             :     useAsm = sc->isFunctionBox() && sc->asFunctionBox()->useAsmOrInsideUseAsm();
     533           0 : 
     534             :     JSFunction* fun = function();
     535             : 
     536           0 :     // Arrow functions don't have their own `this` binding.
     537           0 :     if (fun->isArrow()) {
     538           0 :         allowNewTarget_ = sc->allowNewTarget();
     539           0 :         allowSuperProperty_ = sc->allowSuperProperty();
     540           0 :         allowSuperCall_ = sc->allowSuperCall();
     541           0 :         needsThisTDZChecks_ = sc->needsThisTDZChecks();
     542             :         thisBinding_ = sc->thisBinding();
     543           0 :     } else {
     544           0 :         allowNewTarget_ = true;
     545             :         allowSuperProperty_ = fun->allowSuperProperty();
     546           0 : 
     547           0 :         if (IsConstructorKind(kind)) {
     548           0 :             auto stmt = enclosing->findInnermostStatement<ParseContext::ClassStatement>();
     549           0 :             MOZ_ASSERT(stmt);
     550             :             stmt->constructorBox = this;
     551           0 : 
     552           0 :             if (kind == FunctionSyntaxKind::DerivedClassConstructor) {
     553           0 :                 setDerivedClassConstructor();
     554           0 :                 allowSuperCall_ = true;
     555             :                 needsThisTDZChecks_ = true;
     556             :             }
     557             :         }
     558           0 : 
     559             :         thisBinding_ = ThisBinding::Function;
     560             :     }
     561           0 : 
     562           0 :     if (sc->inWith()) {
     563             :         inWith_ = true;
     564             :     } else {
     565           0 :         auto isWith = [](ParseContext::Statement* stmt) {
     566             :             return stmt->kind() == StatementKind::With;
     567             :         };
     568           0 : 
     569             :         inWith_ = enclosing->findInnermostStatement(isWith);
     570           0 :     }
     571             : }
     572             : 
     573           0 : void
     574             : FunctionBox::initWithEnclosingScope(Scope* enclosingScope)
     575           0 : {
     576           0 :     if (!function()->isArrow()) {
     577           0 :         allowNewTarget_ = true;
     578             :         allowSuperProperty_ = function()->allowSuperProperty();
     579           0 : 
     580           0 :         if (isDerivedClassConstructor()) {
     581           0 :             setDerivedClassConstructor();
     582           0 :             allowSuperCall_ = true;
     583             :             needsThisTDZChecks_ = true;
     584             :         }
     585           0 : 
     586             :         thisBinding_ = ThisBinding::Function;
     587           0 :     } else {
     588           0 :         computeAllowSyntax(enclosingScope);
     589             :         computeThisBinding(enclosingScope);
     590             :     }
     591           0 : 
     592           0 :     computeInWith(enclosingScope);
     593             : }
     594             : 
     595             : template <class ParseHandler, typename CharT>
     596           0 : inline typename GeneralParser<ParseHandler, CharT>::FinalParser*
     597             : GeneralParser<ParseHandler, CharT>::asFinalParser()
     598             : {
     599             :     static_assert(mozilla::IsBaseOf<GeneralParser<ParseHandler, CharT>, FinalParser>::value,
     600             :                   "inheritance relationship required by the static_cast<> below");
     601           0 : 
     602             :     return static_cast<FinalParser*>(this);
     603             : }
     604             : 
     605             : template <class ParseHandler, typename CharT>
     606           0 : inline const typename GeneralParser<ParseHandler, CharT>::FinalParser*
     607             : GeneralParser<ParseHandler, CharT>::asFinalParser() const
     608             : {
     609             :     static_assert(mozilla::IsBaseOf<GeneralParser<ParseHandler, CharT>, FinalParser>::value,
     610             :                   "inheritance relationship required by the static_cast<> below");
     611           0 : 
     612             :     return static_cast<const FinalParser*>(this);
     613             : }
     614             : 
     615             : template <class ParseHandler, typename CharT>
     616           0 : void
     617             : GeneralParser<ParseHandler, CharT>::error(unsigned errorNumber, ...)
     618             : {
     619           0 :     va_list args;
     620             :     va_start(args, errorNumber);
     621           0 : 
     622           0 :     ErrorMetadata metadata;
     623           0 :     if (tokenStream.computeErrorMetadata(&metadata, pos().begin))
     624             :         ReportCompileError(context, std::move(metadata), nullptr, JSREPORT_ERROR, errorNumber, args);
     625           0 : 
     626           0 :     va_end(args);
     627             : }
     628             : 
     629             : template <class ParseHandler, typename CharT>
     630           0 : void
     631             : GeneralParser<ParseHandler, CharT>::errorWithNotes(UniquePtr<JSErrorNotes> notes,
     632             :                                                    unsigned errorNumber, ...)
     633             : {
     634           0 :     va_list args;
     635             :     va_start(args, errorNumber);
     636           0 : 
     637           0 :     ErrorMetadata metadata;
     638           0 :     if (tokenStream.computeErrorMetadata(&metadata, pos().begin)) {
     639             :         ReportCompileError(context, std::move(metadata), std::move(notes), JSREPORT_ERROR, errorNumber,
     640             :                            args);
     641             :     }
     642           0 : 
     643           0 :     va_end(args);
     644             : }
     645             : 
     646             : template <class ParseHandler, typename CharT>
     647           0 : void
     648             : GeneralParser<ParseHandler, CharT>::errorAt(uint32_t offset, unsigned errorNumber, ...)
     649             : {
     650           0 :     va_list args;
     651             :     va_start(args, errorNumber);
     652           0 : 
     653           0 :     ErrorMetadata metadata;
     654           0 :     if (tokenStream.computeErrorMetadata(&metadata, offset))
     655             :         ReportCompileError(context, std::move(metadata), nullptr, JSREPORT_ERROR, errorNumber, args);
     656           0 : 
     657           0 :     va_end(args);
     658             : }
     659             : 
     660             : template <class ParseHandler, typename CharT>
     661           0 : void
     662             : GeneralParser<ParseHandler, CharT>::errorWithNotesAt(UniquePtr<JSErrorNotes> notes,
     663             :                                                      uint32_t offset, unsigned errorNumber, ...)
     664             : {
     665           0 :     va_list args;
     666             :     va_start(args, errorNumber);
     667           0 : 
     668           0 :     ErrorMetadata metadata;
     669           0 :     if (tokenStream.computeErrorMetadata(&metadata, offset)) {
     670             :         ReportCompileError(context, std::move(metadata), std::move(notes), JSREPORT_ERROR, errorNumber,
     671             :                            args);
     672             :     }
     673           0 : 
     674           0 :     va_end(args);
     675             : }
     676             : 
     677             : template <class ParseHandler, typename CharT>
     678           0 : bool
     679             : GeneralParser<ParseHandler, CharT>::warning(unsigned errorNumber, ...)
     680             : {
     681           0 :     va_list args;
     682             :     va_start(args, errorNumber);
     683           0 : 
     684             :     ErrorMetadata metadata;
     685           0 :     bool result =
     686           0 :         tokenStream.computeErrorMetadata(&metadata, pos().begin) &&
     687             :         anyChars.compileWarning(std::move(metadata), nullptr, JSREPORT_WARNING, errorNumber, args);
     688           0 : 
     689           0 :     va_end(args);
     690             :     return result;
     691             : }
     692             : 
     693             : template <class ParseHandler, typename CharT>
     694           0 : bool
     695             : GeneralParser<ParseHandler, CharT>::warningAt(uint32_t offset, unsigned errorNumber, ...)
     696             : {
     697           0 :     va_list args;
     698             :     va_start(args, errorNumber);
     699           0 : 
     700           0 :     ErrorMetadata metadata;
     701           0 :     bool result = tokenStream.computeErrorMetadata(&metadata, offset);
     702           0 :     if (result) {
     703           0 :         result =
     704             :             anyChars.compileWarning(std::move(metadata), nullptr, JSREPORT_WARNING, errorNumber, args);
     705             :     }
     706           0 : 
     707           0 :     va_end(args);
     708             :     return result;
     709             : }
     710             : 
     711             : template <class ParseHandler, typename CharT>
     712           0 : bool
     713             : GeneralParser<ParseHandler, CharT>::extraWarning(unsigned errorNumber, ...)
     714             : {
     715           0 :     va_list args;
     716             :     va_start(args, errorNumber);
     717             : 
     718           0 :     bool result =
     719             :         tokenStream.reportExtraWarningErrorNumberVA(nullptr, pos().begin, errorNumber, &args);
     720           0 : 
     721           0 :     va_end(args);
     722             :     return result;
     723             : }
     724             : 
     725             : template <class ParseHandler, typename CharT>
     726           0 : bool
     727             : GeneralParser<ParseHandler, CharT>::extraWarningAt(uint32_t offset, unsigned errorNumber, ...)
     728             : {
     729           0 :     va_list args;
     730             :     va_start(args, errorNumber);
     731             : 
     732           0 :     bool result =
     733             :         tokenStream.reportExtraWarningErrorNumberVA(nullptr, offset, errorNumber, &args);
     734           0 : 
     735           0 :     va_end(args);
     736             :     return result;
     737             : }
     738             : 
     739             : template <class ParseHandler, typename CharT>
     740           0 : bool
     741             : GeneralParser<ParseHandler, CharT>::strictModeError(unsigned errorNumber, ...)
     742             : {
     743           0 :     va_list args;
     744             :     va_start(args, errorNumber);
     745             : 
     746           0 :     bool res =
     747           0 :         tokenStream.reportStrictModeErrorNumberVA(nullptr, pos().begin, pc->sc()->strict(),
     748             :                                                   errorNumber, &args);
     749           0 : 
     750           0 :     va_end(args);
     751             :     return res;
     752             : }
     753             : 
     754             : template <class ParseHandler, typename CharT>
     755           0 : bool
     756             : GeneralParser<ParseHandler, CharT>::strictModeErrorAt(uint32_t offset, unsigned errorNumber, ...)
     757             : {
     758           0 :     va_list args;
     759             :     va_start(args, errorNumber);
     760             : 
     761           0 :     bool res =
     762           0 :         tokenStream.reportStrictModeErrorNumberVA(nullptr, offset, pc->sc()->strict(),
     763             :                                                   errorNumber, &args);
     764           0 : 
     765           0 :     va_end(args);
     766             :     return res;
     767             : }
     768             : 
     769           0 : bool
     770             : ParserBase::warningNoOffset(unsigned errorNumber, ...)
     771             : {
     772           0 :     va_list args;
     773             :     va_start(args, errorNumber);
     774           0 : 
     775           0 :     ErrorMetadata metadata;
     776             :     anyChars.computeErrorMetadataNoOffset(&metadata);
     777             : 
     778           0 :     bool result =
     779             :         anyChars.compileWarning(std::move(metadata), nullptr, JSREPORT_WARNING, errorNumber, args);
     780           0 : 
     781           0 :     va_end(args);
     782             :     return result;
     783             : }
     784             : 
     785           0 : void
     786             : ParserBase::errorNoOffset(unsigned errorNumber, ...)
     787             : {
     788           0 :     va_list args;
     789             :     va_start(args, errorNumber);
     790           0 : 
     791           0 :     ErrorMetadata metadata;
     792             :     anyChars.computeErrorMetadataNoOffset(&metadata);
     793           0 : 
     794             :     ReportCompileError(context, std::move(metadata), nullptr, JSREPORT_ERROR, errorNumber, args);
     795           0 : 
     796           0 :     va_end(args);
     797             : }
     798           0 : 
     799             : ParserBase::ParserBase(JSContext* cx, LifoAlloc& alloc,
     800             :                        const ReadOnlyCompileOptions& options,
     801             :                        bool foldConstants,
     802             :                        UsedNameTracker& usedNames,
     803           0 :                        ScriptSourceObject* sourceObject,
     804             :                        ParseGoal parseGoal)
     805             :   : AutoGCRooter(cx, AutoGCRooter::Tag::Parser),
     806             :     context(cx),
     807           0 :     alloc(alloc),
     808             :     anyChars(cx, options, thisForCtor()),
     809             :     traceListHead(nullptr),
     810             :     pc(nullptr),
     811             :     usedNames(usedNames),
     812             :     ss(nullptr),
     813             :     sourceObject(cx, sourceObject),
     814             :     keepAtoms(cx),
     815             :     foldConstants(foldConstants),
     816             : #ifdef DEBUG
     817             :     checkOptionsCalled(false),
     818             : #endif
     819             :     isUnexpectedEOF_(false),
     820           0 :     awaitHandling_(AwaitIsName),
     821             :     parseGoal_(uint8_t(parseGoal))
     822           0 : {
     823           0 :     cx->frontendCollectionPool().addActiveCompilation();
     824           0 :     tempPoolMark = alloc.mark();
     825             : }
     826             : 
     827           0 : bool
     828             : ParserBase::checkOptions()
     829             : {
     830           0 : #ifdef DEBUG
     831             :     checkOptionsCalled = true;
     832             : #endif
     833           0 : 
     834             :     return anyChars.checkOptions();
     835             : }
     836           0 : 
     837             : ParserBase::~ParserBase()
     838           0 : {
     839             :     MOZ_ASSERT(checkOptionsCalled);
     840           0 : 
     841             :     alloc.release(tempPoolMark);
     842             : 
     843             :     /*
     844             :      * The parser can allocate enormous amounts of memory for large functions.
     845             :      * Eagerly free the memory now (which otherwise won't be freed until the
     846             :      * next GC) to avoid unnecessary OOMs.
     847           0 :      */
     848             :     alloc.freeAllIfHugeAndUnused();
     849           0 : 
     850           0 :     context->frontendCollectionPool().removeActiveCompilation();
     851             : }
     852             : 
     853           0 : template <class ParseHandler>
     854             : PerHandlerParser<ParseHandler>::PerHandlerParser(JSContext* cx, LifoAlloc& alloc,
     855             :                                                  const ReadOnlyCompileOptions& options,
     856             :                                                  bool foldConstants, UsedNameTracker& usedNames,
     857             :                                                  LazyScript* lazyOuterFunction,
     858             :                                                  ScriptSourceObject* sourceObject,
     859             :                                                  ParseGoal parseGoal)
     860           0 :   : ParserBase(cx, alloc, options, foldConstants, usedNames, sourceObject, parseGoal),
     861             :     handler(cx, alloc, lazyOuterFunction)
     862             : {
     863           0 : 
     864             : }
     865             : 
     866           0 : template <class ParseHandler, typename CharT>
     867             : GeneralParser<ParseHandler, CharT>::GeneralParser(JSContext* cx, LifoAlloc& alloc,
     868             :                                                   const ReadOnlyCompileOptions& options,
     869             :                                                   const CharT* chars, size_t length,
     870             :                                                   bool foldConstants,
     871             :                                                   UsedNameTracker& usedNames,
     872             :                                                   SyntaxParser* syntaxParser,
     873             :                                                   LazyScript* lazyOuterFunction,
     874             :                                                   ScriptSourceObject* sourceObject,
     875             :                                                   ParseGoal parseGoal)
     876           0 :   : Base(cx, alloc, options, foldConstants, usedNames, lazyOuterFunction, sourceObject, parseGoal),
     877             :     tokenStream(cx, options, chars, length)
     878             : {
     879             :     // The Mozilla specific JSOPTION_EXTRA_WARNINGS option adds extra warnings
     880             :     // which are not generated if functions are parsed lazily. Note that the
     881           0 :     // standard "use strict" does not inhibit lazy parsing.
     882           0 :     if (options.extraWarningsOption)
     883             :         disableSyntaxParser();
     884             :     else
     885           0 :         setSyntaxParser(syntaxParser);
     886             : }
     887             : 
     888             : template <typename CharT>
     889           0 : void
     890             : Parser<SyntaxParseHandler, CharT>::setAwaitHandling(AwaitHandling awaitHandling)
     891           0 : {
     892           0 :     this->awaitHandling_ = awaitHandling;
     893             : }
     894             : 
     895             : template <typename CharT>
     896           0 : void
     897             : Parser<FullParseHandler, CharT>::setAwaitHandling(AwaitHandling awaitHandling)
     898           0 : {
     899           0 :     this->awaitHandling_ = awaitHandling;
     900           0 :     if (SyntaxParser* syntaxParser = getSyntaxParser())
     901           0 :         syntaxParser->setAwaitHandling(awaitHandling);
     902             : }
     903             : 
     904             : template <class ParseHandler, typename CharT>
     905           0 : inline void
     906             : GeneralParser<ParseHandler, CharT>::setAwaitHandling(AwaitHandling awaitHandling)
     907           0 : {
     908           0 :     asFinalParser()->setAwaitHandling(awaitHandling);
     909             : }
     910             : 
     911           0 : ObjectBox*
     912             : ParserBase::newObjectBox(JSObject* obj)
     913           0 : {
     914             :     MOZ_ASSERT(obj);
     915             : 
     916             :     /*
     917             :      * We use JSContext.tempLifoAlloc to allocate parsed objects and place them
     918             :      * on a list in this Parser to ensure GC safety. Thus the tempLifoAlloc
     919             :      * arenas containing the entries must be alive until we are done with
     920             :      * scanning, parsing and code generation for the whole script or top-level
     921             :      * function.
     922             :      */
     923           0 : 
     924           0 :     ObjectBox* objbox = alloc.template new_<ObjectBox>(obj, traceListHead);
     925           0 :     if (!objbox) {
     926           0 :         ReportOutOfMemory(context);
     927             :         return nullptr;
     928             :     }
     929           0 : 
     930             :     traceListHead = objbox;
     931           0 : 
     932             :     return objbox;
     933             : }
     934             : 
     935             : template <class ParseHandler>
     936           0 : FunctionBox*
     937             : PerHandlerParser<ParseHandler>::newFunctionBox(Node fn, JSFunction* fun, uint32_t toStringStart,
     938             :                                                Directives inheritedDirectives,
     939             :                                                GeneratorKind generatorKind,
     940             :                                                FunctionAsyncKind asyncKind)
     941           0 : {
     942             :     MOZ_ASSERT(fun);
     943             : 
     944             :     /*
     945             :      * We use JSContext.tempLifoAlloc to allocate parsed objects and place them
     946             :      * on a list in this Parser to ensure GC safety. Thus the tempLifoAlloc
     947             :      * arenas containing the entries must be alive until we are done with
     948             :      * scanning, parsing and code generation for the whole script or top-level
     949             :      * function.
     950             :      */
     951           0 :     FunctionBox* funbox =
     952           0 :         alloc.new_<FunctionBox>(context, traceListHead, fun, toStringStart, inheritedDirectives,
     953           0 :                                 options().extraWarningsOption, generatorKind, asyncKind);
     954           0 :     if (!funbox) {
     955           0 :         ReportOutOfMemory(context);
     956             :         return nullptr;
     957             :     }
     958           0 : 
     959           0 :     traceListHead = funbox;
     960           0 :     if (fn)
     961             :         handler.setFunctionBox(fn, funbox);
     962             : 
     963             :     return funbox;
     964             : }
     965           0 : 
     966           0 : ModuleSharedContext::ModuleSharedContext(JSContext* cx, ModuleObject* module,
     967             :                                          Scope* enclosingScope, ModuleBuilder& builder)
     968             :   : SharedContext(cx, Kind::Module, Directives(true), false),
     969             :     module_(cx, module),
     970             :     enclosingScope_(cx, enclosingScope),
     971           0 :     bindings(cx),
     972             :     builder(builder)
     973           0 : {
     974           0 :     thisBinding_ = ThisBinding::Module;
     975             : }
     976             : 
     977           0 : void
     978             : ParserBase::trace(JSTracer* trc)
     979           0 : {
     980           0 :     ObjectBox::TraceList(trc, traceListHead);
     981             : }
     982             : 
     983           0 : void
     984             : TraceParser(JSTracer* trc, AutoGCRooter* parser)
     985           0 : {
     986           0 :     static_cast<ParserBase*>(parser)->trace(trc);
     987             : }
     988             : 
     989           0 : bool
     990             : ParserBase::setSourceMapInfo()
     991             : {
     992           0 :     // Not all clients initialize ss. Can't update info to an object that isn't there.
     993             :     if (!ss)
     994             :         return true;
     995           0 : 
     996           0 :     if (anyChars.hasDisplayURL()) {
     997             :         if (!ss->setDisplayURL(context, anyChars.displayURL()))
     998             :             return false;
     999             :     }
    1000           0 : 
    1001           0 :     if (anyChars.hasSourceMapURL()) {
    1002           0 :         MOZ_ASSERT(!ss->hasSourceMapURL());
    1003             :         if (!ss->setSourceMapURL(context, anyChars.sourceMapURL()))
    1004             :             return false;
    1005             :     }
    1006             : 
    1007             :     /*
    1008             :      * Source map URLs passed as a compile option (usually via a HTTP source map
    1009             :      * header) override any source map urls passed as comment pragmas.
    1010           0 :      */
    1011             :     if (options().sourceMapURL()) {
    1012           0 :         // Warn about the replacement, but use the new one.
    1013           0 :         if (ss->hasSourceMapURL()) {
    1014           0 :             if (!warningNoOffset(JSMSG_ALREADY_HAS_PRAGMA,
    1015             :                                  ss->filename(), "//# sourceMappingURL"))
    1016             :             {
    1017             :                 return false;
    1018             :             }
    1019             :         }
    1020           0 : 
    1021             :         if (!ss->setSourceMapURL(context, options().sourceMapURL()))
    1022             :             return false;
    1023             :     }
    1024             : 
    1025             :     return true;
    1026             : }
    1027             : 
    1028             : 
    1029             : /*
    1030             :  * Parse a top-level JS script.
    1031             :  */
    1032             : template <class ParseHandler, typename CharT>
    1033           0 : typename ParseHandler::Node
    1034             : GeneralParser<ParseHandler, CharT>::parse()
    1035           0 : {
    1036             :     MOZ_ASSERT(checkOptionsCalled);
    1037           0 : 
    1038             :     Directives directives(options().strictOption);
    1039           0 :     GlobalSharedContext globalsc(context, ScopeKind::Global,
    1040           0 :                                  directives, options().extraWarningsOption);
    1041           0 :     SourceParseContext globalpc(this, &globalsc, /* newDirectives = */ nullptr);
    1042             :     if (!globalpc.init())
    1043             :         return null();
    1044           0 : 
    1045           0 :     ParseContext::VarScope varScope(this);
    1046             :     if (!varScope.init(pc))
    1047             :         return null();
    1048           0 : 
    1049           0 :     Node pn = statementList(YieldIsName);
    1050             :     if (!pn)
    1051             :         return null();
    1052             : 
    1053           0 :     TokenKind tt;
    1054             :     if (!tokenStream.getToken(&tt, TokenStream::Operand))
    1055           0 :         return null();
    1056           0 :     if (tt != TokenKind::Eof) {
    1057           0 :         error(JSMSG_GARBAGE_AFTER_INPUT, "script", TokenKindToDesc(tt));
    1058             :         return null();
    1059           0 :     }
    1060           0 :     if (foldConstants) {
    1061             :         if (!FoldConstants(context, &pn, this))
    1062             :             return null();
    1063             :     }
    1064           0 : 
    1065             :     return pn;
    1066             : }
    1067             : 
    1068             : /*
    1069             :  * Strict mode forbids introducing new definitions for 'eval', 'arguments',
    1070             :  * 'let', 'static', 'yield', or for any strict mode reserved word.
    1071             :  */
    1072           0 : bool
    1073             : ParserBase::isValidStrictBinding(PropertyName* name)
    1074           0 : {
    1075           0 :     TokenKind tt = ReservedWordTokenKind(name);
    1076           0 :     if (tt == TokenKind::Name) {
    1077           0 :         return name != context->names().eval &&
    1078             :                name != context->names().arguments;
    1079           0 :     }
    1080           0 :     return tt != TokenKind::Let &&
    1081           0 :            tt != TokenKind::Static &&
    1082           0 :            tt != TokenKind::Yield &&
    1083             :            !TokenKindIsStrictReservedWord(tt);
    1084             : }
    1085             : 
    1086             : /*
    1087             :  * Returns true if all parameter names are valid strict mode binding names and
    1088             :  * no duplicate parameter names are present.
    1089             :  */
    1090           0 : bool
    1091             : ParserBase::hasValidSimpleStrictParameterNames()
    1092           0 : {
    1093             :     MOZ_ASSERT(pc->isFunctionBox() && pc->functionBox()->hasSimpleParameterList());
    1094           0 : 
    1095             :     if (pc->functionBox()->hasDuplicateParameters)
    1096             :         return false;
    1097           0 : 
    1098           0 :     for (auto* name : pc->positionalFormalParameterNames()) {
    1099           0 :         MOZ_ASSERT(name);
    1100             :         if (!isValidStrictBinding(name->asPropertyName()))
    1101             :             return false;
    1102             :     }
    1103             :     return true;
    1104             : }
    1105             : 
    1106             : template <class ParseHandler, typename CharT>
    1107           0 : void
    1108             : GeneralParser<ParseHandler, CharT>::reportMissingClosing(unsigned errorNumber, unsigned noteNumber,
    1109             :                                                          uint32_t openedPos)
    1110           0 : {
    1111           0 :     auto notes = MakeUnique<JSErrorNotes>();
    1112           0 :     if (!notes) {
    1113           0 :         ReportOutOfMemory(pc->sc()->context);
    1114             :         return;
    1115             :     }
    1116             : 
    1117           0 :     uint32_t line, column;
    1118             :     anyChars.srcCoords.lineNumAndColumnIndex(openedPos, &line, &column);
    1119           0 : 
    1120             :     const size_t MaxWidth = sizeof("4294967295");
    1121           0 :     char columnNumber[MaxWidth];
    1122             :     SprintfLiteral(columnNumber, "%" PRIu32, column);
    1123           0 :     char lineNumber[MaxWidth];
    1124             :     SprintfLiteral(lineNumber, "%" PRIu32, line);
    1125           0 : 
    1126             :     if (!notes->addNoteASCII(pc->sc()->context,
    1127             :                              getFilename(), line, column,
    1128             :                              GetErrorMessage, nullptr,
    1129             :                              noteNumber, lineNumber, columnNumber))
    1130             :     {
    1131             :         return;
    1132             :     }
    1133           0 : 
    1134             :     errorWithNotes(std::move(notes), errorNumber);
    1135             : }
    1136             : 
    1137             : template <class ParseHandler, typename CharT>
    1138           0 : void
    1139             : GeneralParser<ParseHandler, CharT>::reportRedeclaration(HandlePropertyName name,
    1140             :                                                         DeclarationKind prevKind,
    1141             :                                                         TokenPos pos, uint32_t prevPos)
    1142           0 : {
    1143           0 :     JSAutoByteString bytes;
    1144           0 :     if (!AtomToPrintableString(context, name, &bytes))
    1145             :         return;
    1146           0 : 
    1147           0 :     if (prevPos == DeclaredNameInfo::npos) {
    1148           0 :         errorAt(pos.begin, JSMSG_REDECLARED_VAR, DeclarationKindString(prevKind), bytes.ptr());
    1149             :         return;
    1150             :     }
    1151           0 : 
    1152           0 :     auto notes = MakeUnique<JSErrorNotes>();
    1153           0 :     if (!notes) {
    1154           0 :         ReportOutOfMemory(pc->sc()->context);
    1155             :         return;
    1156             :     }
    1157             : 
    1158           0 :     uint32_t line, column;
    1159             :     anyChars.srcCoords.lineNumAndColumnIndex(prevPos, &line, &column);
    1160           0 : 
    1161             :     const size_t MaxWidth = sizeof("4294967295");
    1162           0 :     char columnNumber[MaxWidth];
    1163             :     SprintfLiteral(columnNumber, "%" PRIu32, column);
    1164           0 :     char lineNumber[MaxWidth];
    1165             :     SprintfLiteral(lineNumber, "%" PRIu32, line);
    1166           0 : 
    1167             :     if (!notes->addNoteASCII(pc->sc()->context,
    1168             :                              getFilename(), line, column,
    1169             :                              GetErrorMessage, nullptr,
    1170             :                              JSMSG_REDECLARED_PREV,
    1171             :                              lineNumber, columnNumber))
    1172             :     {
    1173             :         return;
    1174             :     }
    1175           0 : 
    1176             :     errorWithNotesAt(std::move(notes), pos.begin, JSMSG_REDECLARED_VAR,
    1177             :                      DeclarationKindString(prevKind), bytes.ptr());
    1178             : }
    1179             : 
    1180             : // notePositionalFormalParameter is called for both the arguments of a regular
    1181             : // function definition and the arguments specified by the Function
    1182             : // constructor.
    1183             : //
    1184             : // The 'disallowDuplicateParams' bool indicates whether the use of another
    1185             : // feature (destructuring or default arguments) disables duplicate arguments.
    1186             : // (ECMA-262 requires us to support duplicate parameter names, but, for newer
    1187             : // features, we consider the code to have "opted in" to higher standards and
    1188             : // forbid duplicates.)
    1189             : template <class ParseHandler, typename CharT>
    1190           0 : bool
    1191             : GeneralParser<ParseHandler, CharT>::notePositionalFormalParameter(Node fn, HandlePropertyName name,
    1192             :                                                                   uint32_t beginPos,
    1193             :                                                                   bool disallowDuplicateParams,
    1194             :                                                                   bool* duplicatedParam)
    1195           0 : {
    1196           0 :     if (AddDeclaredNamePtr p = pc->functionScope().lookupDeclaredNameForAdd(name)) {
    1197           0 :         if (disallowDuplicateParams) {
    1198           0 :             error(JSMSG_BAD_DUP_ARGS);
    1199             :             return false;
    1200             :         }
    1201             : 
    1202             :         // Strict-mode disallows duplicate args. We may not know whether we are
    1203             :         // in strict mode or not (since the function body hasn't been parsed).
    1204             :         // In such cases, report will queue up the potential error and return
    1205           0 :         // 'true'.
    1206           0 :         if (pc->sc()->needStrictChecks()) {
    1207           0 :             JSAutoByteString bytes;
    1208           0 :             if (!AtomToPrintableString(context, name, &bytes))
    1209           0 :                 return false;
    1210             :             if (!strictModeError(JSMSG_DUPLICATE_FORMAL, bytes.ptr()))
    1211             :                 return false;
    1212             :         }
    1213           0 : 
    1214             :         *duplicatedParam = true;
    1215           0 :     } else {
    1216           0 :         DeclarationKind kind = DeclarationKind::PositionalFormalParameter;
    1217             :         if (!pc->functionScope().addDeclaredName(pc, p, name, kind, beginPos))
    1218             :             return false;
    1219             :     }
    1220           0 : 
    1221           0 :     if (!pc->positionalFormalParameterNames().append(name)) {
    1222           0 :         ReportOutOfMemory(context);
    1223             :         return false;
    1224             :     }
    1225           0 : 
    1226           0 :     Node paramNode = newName(name);
    1227             :     if (!paramNode)
    1228             :         return false;
    1229           0 : 
    1230           0 :     handler.addFunctionFormalParameter(fn, paramNode);
    1231             :     return true;
    1232             : }
    1233             : 
    1234             : template <class ParseHandler>
    1235           0 : bool
    1236             : PerHandlerParser<ParseHandler>::noteDestructuredPositionalFormalParameter(Node fn, Node destruct)
    1237             : {
    1238             :     // Append an empty name to the positional formals vector to keep track of
    1239           0 :     // argument slots when making FunctionScope::Data.
    1240           0 :     if (!pc->positionalFormalParameterNames().append(nullptr)) {
    1241           0 :         ReportOutOfMemory(context);
    1242             :         return false;
    1243             :     }
    1244           0 : 
    1245           0 :     handler.addFunctionFormalParameter(fn, destruct);
    1246             :     return true;
    1247             : }
    1248             : 
    1249             : static bool
    1250             : DeclarationKindIsVar(DeclarationKind kind)
    1251           0 : {
    1252           0 :     return kind == DeclarationKind::Var ||
    1253           0 :            kind == DeclarationKind::BodyLevelFunction ||
    1254           0 :            kind == DeclarationKind::VarForAnnexBLexicalFunction ||
    1255             :            kind == DeclarationKind::ForOfVar;
    1256             : }
    1257             : 
    1258           0 : Maybe<DeclarationKind>
    1259             : ParseContext::isVarRedeclaredInEval(HandlePropertyName name, DeclarationKind kind)
    1260           0 : {
    1261           0 :     MOZ_ASSERT(DeclarationKindIsVar(kind));
    1262             :     MOZ_ASSERT(sc()->isEvalContext());
    1263             : 
    1264             :     // In the case of eval, we also need to check enclosing VM scopes to see
    1265             :     // if the var declaration is allowed in the context.
    1266             :     //
    1267             :     // This check is necessary in addition to
    1268             :     // js::CheckEvalDeclarationConflicts because we only know during parsing
    1269           0 :     // if a var is bound by for-of.
    1270           0 :     js::Scope* enclosingScope = sc()->compilationEnclosingScope();
    1271           0 :     js::Scope* varScope = EvalScope::nearestVarScopeForDirectEval(enclosingScope);
    1272           0 :     MOZ_ASSERT(varScope);
    1273           0 :     for (ScopeIter si(enclosingScope); si; si++) {
    1274           0 :         for (js::BindingIter bi(si.scope()); bi; bi++) {
    1275             :             if (bi.name() != name)
    1276             :                 continue;
    1277           0 : 
    1278             :             switch (bi.kind()) {
    1279             :               case BindingKind::Let: {
    1280             :                   // Annex B.3.5 allows redeclaring simple (non-destructured)
    1281             :                   // catch parameters with var declarations, except when it
    1282           0 :                   // appears in a for-of.
    1283           0 :                   bool annexB35Allowance = si.kind() == ScopeKind::SimpleCatch &&
    1284           0 :                                            kind != DeclarationKind::ForOfVar;
    1285           0 :                   if (!annexB35Allowance) {
    1286           0 :                       return Some(ScopeKindIsCatch(si.kind())
    1287           0 :                                   ? DeclarationKind::CatchParameter
    1288             :                                   : DeclarationKind::Let);
    1289             :                   }
    1290             :                   break;
    1291             :               }
    1292             : 
    1293           0 :               case BindingKind::Const:
    1294             :                 return Some(DeclarationKind::Const);
    1295             : 
    1296             :               case BindingKind::Import:
    1297             :               case BindingKind::FormalParameter:
    1298             :               case BindingKind::Var:
    1299             :               case BindingKind::NamedLambdaCallee:
    1300             :                 break;
    1301             :             }
    1302             :         }
    1303           0 : 
    1304             :         if (si.scope() == varScope)
    1305             :             break;
    1306             :     }
    1307             : 
    1308             :     return Nothing();
    1309             : }
    1310             : 
    1311           0 : Maybe<DeclarationKind>
    1312             : ParseContext::isVarRedeclaredInInnermostScope(HandlePropertyName name, DeclarationKind kind)
    1313           0 : {
    1314             :     Maybe<DeclarationKind> redeclaredKind;
    1315           0 :     uint32_t unused;
    1316             :     MOZ_ALWAYS_TRUE(tryDeclareVarHelper<DryRunInnermostScopeOnly>(name, kind,
    1317             :                                                                   DeclaredNameInfo::npos,
    1318           0 :                                                                   &redeclaredKind, &unused));
    1319             :     return redeclaredKind;
    1320             : }
    1321             : 
    1322           0 : bool
    1323             : ParseContext::tryDeclareVar(HandlePropertyName name, DeclarationKind kind,
    1324             :                             uint32_t beginPos, Maybe<DeclarationKind>* redeclaredKind,
    1325             :                             uint32_t* prevPos)
    1326           0 : {
    1327             :     return tryDeclareVarHelper<NotDryRun>(name, kind, beginPos, redeclaredKind, prevPos);
    1328             : }
    1329             : 
    1330             : static bool
    1331             : DeclarationKindIsParameter(DeclarationKind kind)
    1332             : {
    1333             :     return kind == DeclarationKind::PositionalFormalParameter ||
    1334             :            kind == DeclarationKind::FormalParameter;
    1335             : }
    1336             : 
    1337             : template <ParseContext::DryRunOption dryRunOption>
    1338           0 : bool
    1339             : ParseContext::tryDeclareVarHelper(HandlePropertyName name, DeclarationKind kind,
    1340             :                                   uint32_t beginPos, Maybe<DeclarationKind>* redeclaredKind,
    1341             :                                   uint32_t* prevPos)
    1342           0 : {
    1343             :     MOZ_ASSERT(DeclarationKindIsVar(kind));
    1344             : 
    1345             :     // It is an early error if a 'var' declaration appears inside a
    1346             :     // scope contour that has a lexical declaration of the same name. For
    1347             :     // example, the following are early errors:
    1348             :     //
    1349             :     //   { let x; var x; }
    1350             :     //   { { var x; } let x; }
    1351             :     //
    1352             :     // And the following are not:
    1353             :     //
    1354             :     //   { var x; var x; }
    1355             :     //   { { let x; } var x; }
    1356           0 : 
    1357           0 :     for (ParseContext::Scope* scope = innermostScope();
    1358           0 :          scope != varScope().enclosing();
    1359             :          scope = scope->enclosing())
    1360           0 :     {
    1361           0 :         if (AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name)) {
    1362           0 :             DeclarationKind declaredKind = p->value()->kind();
    1363             :             if (DeclarationKindIsVar(declaredKind)) {
    1364             :                 // Any vars that are redeclared as body-level functions must
    1365             :                 // be recorded as body-level functions.
    1366             :                 //
    1367             :                 // In the case of global and eval scripts, GlobalDeclaration-
    1368             :                 // Instantiation [1] and EvalDeclarationInstantiation [2]
    1369             :                 // check for the declarability of global var and function
    1370             :                 // bindings via CanDeclareVar [3] and CanDeclareGlobal-
    1371             :                 // Function [4]. CanDeclareGlobalFunction is strictly more
    1372             :                 // restrictive than CanDeclareGlobalVar, so record the more
    1373             :                 // restrictive kind. These semantics are implemented in
    1374             :                 // CheckCanDeclareGlobalBinding.
    1375             :                 //
    1376             :                 // For a var previously declared as ForOfVar, this previous
    1377             :                 // DeclarationKind is used only to check for if the
    1378             :                 // 'arguments' binding should be declared. Since body-level
    1379             :                 // functions shadow 'arguments' [5], it is correct to alter
    1380             :                 // the kind to BodyLevelFunction. See
    1381             :                 // declareFunctionArgumentsObject.
    1382             :                 //
    1383             :                 // VarForAnnexBLexicalFunction declarations are declared when
    1384             :                 // the var scope exits. It is not possible for a var to be
    1385             :                 // previously declared as VarForAnnexBLexicalFunction and
    1386             :                 // checked for redeclaration.
    1387             :                 //
    1388             :                 // [1] ES 15.1.11
    1389             :                 // [2] ES 18.2.1.3
    1390             :                 // [3] ES 8.1.1.4.15
    1391             :                 // [4] ES 8.1.1.4.16
    1392           0 :                 // [5] ES 9.2.12
    1393           0 :                 if (dryRunOption == NotDryRun && kind == DeclarationKind::BodyLevelFunction) {
    1394           0 :                     MOZ_ASSERT(declaredKind != DeclarationKind::VarForAnnexBLexicalFunction);
    1395             :                     p->value()->alterKind(kind);
    1396           0 :                 }
    1397             :             } else if (!DeclarationKindIsParameter(declaredKind)) {
    1398             :                 // Annex B.3.5 allows redeclaring simple (non-destructured)
    1399             :                 // catch parameters with var declarations, except when it
    1400           0 :                 // appears in a for-of.
    1401           0 :                 bool annexB35Allowance = declaredKind == DeclarationKind::SimpleCatchParameter &&
    1402             :                                          kind != DeclarationKind::ForOfVar;
    1403             : 
    1404           0 :                 // Annex B.3.3 allows redeclaring functions in the same block.
    1405           0 :                 bool annexB33Allowance = declaredKind == DeclarationKind::SloppyLexicalFunction &&
    1406           0 :                                          kind == DeclarationKind::VarForAnnexBLexicalFunction &&
    1407             :                                          scope == innermostScope();
    1408           0 : 
    1409           0 :                 if (!annexB35Allowance && !annexB33Allowance) {
    1410           0 :                     *redeclaredKind = Some(declaredKind);
    1411           0 :                     *prevPos = p->value()->pos();
    1412             :                     return true;
    1413           0 :                 }
    1414           0 :             } else if (kind == DeclarationKind::VarForAnnexBLexicalFunction) {
    1415             :                 MOZ_ASSERT(DeclarationKindIsParameter(declaredKind));
    1416             : 
    1417             :                 // Annex B.3.3.1 disallows redeclaring parameter names.
    1418             :                 // We don't need to set *prevPos here since this case is not
    1419           0 :                 // an error.
    1420           0 :                 *redeclaredKind = Some(declaredKind);
    1421             :                 return true;
    1422             :             }
    1423           0 :         } else if (dryRunOption == NotDryRun) {
    1424             :             if (!scope->addDeclaredName(this, p, name, kind, beginPos))
    1425             :                 return false;
    1426             :         }
    1427             : 
    1428             :         // DryRunOption is used for propagating Annex B functions: we don't
    1429             :         // want to declare the synthesized Annex B vars until we exit the var
    1430             :         // scope and know that no early errors would have occurred. In order
    1431             :         // to avoid quadratic search, we only check for var redeclarations in
    1432             :         // the innermost scope when doing a dry run.
    1433           0 :         if (dryRunOption == DryRunInnermostScopeOnly)
    1434             :             break;
    1435             :     }
    1436           0 : 
    1437           0 :     if (!sc()->strict() && sc()->isEvalContext() &&
    1438             :         (dryRunOption == NotDryRun || innermostScope() == &varScope()))
    1439           0 :     {
    1440             :         *redeclaredKind = isVarRedeclaredInEval(name, kind);
    1441           0 :         // We don't have position information at runtime.
    1442             :         *prevPos = DeclaredNameInfo::npos;
    1443             :     }
    1444             : 
    1445             :     return true;
    1446             : }
    1447             : 
    1448           0 : bool
    1449             : ParseContext::annexBAppliesToLexicalFunctionInInnermostScope(FunctionBox* funbox)
    1450           0 : {
    1451             :     MOZ_ASSERT(!sc()->strict());
    1452           0 : 
    1453             :     RootedPropertyName name(sc()->context, funbox->function()->explicitName()->asPropertyName());
    1454           0 :     Maybe<DeclarationKind> redeclaredKind =
    1455             :         isVarRedeclaredInInnermostScope(name, DeclarationKind::VarForAnnexBLexicalFunction);
    1456           0 : 
    1457           0 :     if (!redeclaredKind && isFunctionBox()) {
    1458           0 :         Scope& funScope = functionScope();
    1459             :         if (&funScope != &varScope()) {
    1460             :             // Annex B.3.3.1 disallows redeclaring parameter names. In the
    1461             :             // presence of parameter expressions, parameter names are on the
    1462             :             // function scope, which encloses the var scope. This means the
    1463             :             // isVarRedeclaredInInnermostScope call above would not catch this
    1464           0 :             // case, so test it manually.
    1465           0 :             if (AddDeclaredNamePtr p = funScope.lookupDeclaredNameForAdd(name)) {
    1466           0 :                 DeclarationKind declaredKind = p->value()->kind();
    1467           0 :                 if (DeclarationKindIsParameter(declaredKind))
    1468             :                     redeclaredKind = Some(declaredKind);
    1469           0 :                 else
    1470             :                     MOZ_ASSERT(FunctionScope::isSpecialName(sc()->context, name));
    1471             :             }
    1472             :         }
    1473             :     }
    1474             : 
    1475             :     // If an early error would have occurred already, this function should not
    1476           0 :     // exhibit Annex B.3.3 semantics.
    1477             :     return !redeclaredKind;
    1478             : }
    1479             : 
    1480             : template <class ParseHandler, typename CharT>
    1481           0 : bool
    1482             : GeneralParser<ParseHandler, CharT>::checkLexicalDeclarationDirectlyWithinBlock(ParseContext::Statement& stmt,
    1483             :                                                                                DeclarationKind kind,
    1484             :                                                                                TokenPos pos)
    1485           0 : {
    1486             :     MOZ_ASSERT(DeclarationKindIsLexical(kind));
    1487             : 
    1488             :     // It is an early error to declare a lexical binding not directly
    1489           0 :     // within a block.
    1490           0 :     if (!StatementKindIsBraced(stmt.kind()) &&
    1491             :         stmt.kind() != StatementKind::ForLoopLexicalHead)
    1492           0 :     {
    1493           0 :         errorAt(pos.begin,
    1494             :                 stmt.kind() == StatementKind::Label
    1495             :                 ? JSMSG_LEXICAL_DECL_LABEL
    1496             :                 : JSMSG_LEXICAL_DECL_NOT_IN_BLOCK,
    1497           0 :                 DeclarationKindString(kind));
    1498             :         return false;
    1499             :     }
    1500             : 
    1501             :     return true;
    1502             : }
    1503             : 
    1504             : template <class ParseHandler, typename CharT>
    1505           0 : bool
    1506             : GeneralParser<ParseHandler, CharT>::noteDeclaredName(HandlePropertyName name, DeclarationKind kind,
    1507             :                                                      TokenPos pos)
    1508             : {
    1509             :     // The asm.js validator does all its own symbol-table management so, as an
    1510           0 :     // optimization, avoid doing any work here.
    1511             :     if (pc->useAsmOrInsideUseAsm())
    1512             :         return true;
    1513           0 : 
    1514             :     switch (kind) {
    1515             :       case DeclarationKind::Var:
    1516             :       case DeclarationKind::BodyLevelFunction:
    1517           0 :       case DeclarationKind::ForOfVar: {
    1518             :         Maybe<DeclarationKind> redeclaredKind;
    1519           0 :         uint32_t prevPos;
    1520           0 :         if (!pc->tryDeclareVar(name, kind, pos.begin, &redeclaredKind, &prevPos))
    1521             :             return false;
    1522           0 : 
    1523           0 :         if (redeclaredKind) {
    1524           0 :             reportRedeclaration(name, *redeclaredKind, pos, prevPos);
    1525             :             return false;
    1526             :         }
    1527           0 : 
    1528             :         break;
    1529             :       }
    1530             : 
    1531           0 :       case DeclarationKind::ModuleBodyLevelFunction: {
    1532             :           MOZ_ASSERT(pc->atModuleLevel());
    1533           0 : 
    1534           0 :           AddDeclaredNamePtr p = pc->varScope().lookupDeclaredNameForAdd(name);
    1535           0 :           if (p) {
    1536           0 :               reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
    1537             :               return false;
    1538             :           }
    1539           0 : 
    1540             :           if (!pc->varScope().addDeclaredName(pc, p, name, kind, pos.begin))
    1541             :               return false;
    1542             : 
    1543           0 :           // Body-level functions in modules are always closed over.
    1544             :           pc->varScope().lookupDeclaredName(name)->value()->setClosedOver();
    1545           0 : 
    1546             :           break;
    1547             :       }
    1548             : 
    1549             :       case DeclarationKind::FormalParameter: {
    1550             :         // It is an early error if any non-positional formal parameter name
    1551             :         // (e.g., destructuring formal parameter) is duplicated.
    1552           0 : 
    1553           0 :         AddDeclaredNamePtr p = pc->functionScope().lookupDeclaredNameForAdd(name);
    1554           0 :         if (p) {
    1555           0 :             error(JSMSG_BAD_DUP_ARGS);
    1556             :             return false;
    1557             :         }
    1558           0 : 
    1559             :         if (!pc->functionScope().addDeclaredName(pc, p, name, kind, pos.begin))
    1560             :             return false;
    1561           0 : 
    1562             :         break;
    1563             :       }
    1564             : 
    1565           0 :       case DeclarationKind::LexicalFunction: {
    1566           0 :         ParseContext::Scope* scope = pc->innermostScope();
    1567           0 :         AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name);
    1568           0 :         if (p) {
    1569           0 :             reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
    1570             :             return false;
    1571             :         }
    1572           0 : 
    1573             :         if (!scope->addDeclaredName(pc, p, name, kind, pos.begin))
    1574             :             return false;
    1575           0 : 
    1576             :         break;
    1577             :       }
    1578             : 
    1579             :       case DeclarationKind::SloppyLexicalFunction: {
    1580             :         // Functions in block have complex allowances in sloppy mode for being
    1581             :         // labelled that other lexical declarations do not have. Those checks
    1582             :         // are more complex than calling checkLexicalDeclarationDirectlyWithin-
    1583             :         // Block and are done in checkFunctionDefinition.
    1584           0 : 
    1585           0 :         ParseContext::Scope* scope = pc->innermostScope();
    1586             :         if (AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name)) {
    1587             :             // It is usually an early error if there is another declaration
    1588             :             // with the same name in the same scope.
    1589             :             //
    1590             :             // Sloppy lexical functions may redeclare other sloppy lexical
    1591           0 :             // functions for web compatibility reasons.
    1592           0 :             if (p->value()->kind() != DeclarationKind::SloppyLexicalFunction) {
    1593           0 :                 reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
    1594             :                 return false;
    1595             :             }
    1596           0 :         } else {
    1597             :             if (!scope->addDeclaredName(pc, p, name, kind, pos.begin))
    1598             :                 return false;
    1599             :         }
    1600           0 : 
    1601             :         break;
    1602             :       }
    1603             : 
    1604             :       case DeclarationKind::Let:
    1605             :       case DeclarationKind::Const:
    1606             :       case DeclarationKind::Class:
    1607             :         // The BoundNames of LexicalDeclaration and ForDeclaration must not
    1608             :         // contain 'let'. (CatchParameter is the only lexical binding form
    1609           0 :         // without this restriction.)
    1610           0 :         if (name == context->names().let) {
    1611           0 :             errorAt(pos.begin, JSMSG_LEXICAL_DECL_DEFINES_LET);
    1612             :             return false;
    1613             :         }
    1614             : 
    1615             :         MOZ_FALLTHROUGH;
    1616             : 
    1617             :       case DeclarationKind::Import:
    1618           0 :         // Module code is always strict, so 'let' is always a keyword and never a name.
    1619             :         MOZ_ASSERT(name != context->names().let);
    1620             :         MOZ_FALLTHROUGH;
    1621             : 
    1622             :       case DeclarationKind::SimpleCatchParameter:
    1623           0 :       case DeclarationKind::CatchParameter: {
    1624           0 :         if (ParseContext::Statement* stmt = pc->innermostStatement()) {
    1625           0 :             if (!checkLexicalDeclarationDirectlyWithinBlock(*stmt, kind, pos))
    1626             :                 return false;
    1627             :         }
    1628           0 : 
    1629             :         ParseContext::Scope* scope = pc->innermostScope();
    1630             : 
    1631             :         // For body-level lexically declared names in a function, it is an
    1632             :         // early error if there is a formal parameter of the same name. This
    1633             :         // needs a special check if there is an extra var scope due to
    1634           0 :         // parameter expressions.
    1635           0 :         if (pc->isFunctionExtraBodyVarScopeInnermost()) {
    1636           0 :             DeclaredNamePtr p = pc->functionScope().lookupDeclaredName(name);
    1637           0 :             if (p && DeclarationKindIsParameter(p->value()->kind())) {
    1638           0 :                 reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
    1639             :                 return false;
    1640             :             }
    1641             :         }
    1642             : 
    1643             :         // It is an early error if there is another declaration with the same
    1644           0 :         // name in the same scope.
    1645           0 :         AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name);
    1646           0 :         if (p) {
    1647           0 :             reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
    1648             :             return false;
    1649             :         }
    1650           0 : 
    1651             :         if (!scope->addDeclaredName(pc, p, name, kind, pos.begin))
    1652             :             return false;
    1653           0 : 
    1654             :         break;
    1655             :       }
    1656             : 
    1657             :       case DeclarationKind::CoverArrowParameter:
    1658             :         // CoverArrowParameter is only used as a placeholder declaration kind.
    1659             :         break;
    1660             : 
    1661           0 :       case DeclarationKind::PositionalFormalParameter:
    1662             :         MOZ_CRASH("Positional formal parameter names should use "
    1663             :                   "notePositionalFormalParameter");
    1664             :         break;
    1665             : 
    1666           0 :       case DeclarationKind::VarForAnnexBLexicalFunction:
    1667             :         MOZ_CRASH("Synthesized Annex B vars should go through "
    1668             :                   "tryDeclareVarForAnnexBLexicalFunction");
    1669             :         break;
    1670             :     }
    1671             : 
    1672             :     return true;
    1673             : }
    1674             : 
    1675           0 : bool
    1676             : ParserBase::noteUsedNameInternal(HandlePropertyName name)
    1677             : {
    1678             :     // The asm.js validator does all its own symbol-table management so, as an
    1679           0 :     // optimization, avoid doing any work here.
    1680             :     if (pc->useAsmOrInsideUseAsm())
    1681             :         return true;
    1682             : 
    1683             :     // Global bindings are properties and not actual bindings; we don't need
    1684             :     // to know if they are closed over. So no need to track used name at the
    1685             :     // global scope. It is not incorrect to track them, this is an
    1686           0 :     // optimization.
    1687           0 :     ParseContext::Scope* scope = pc->innermostScope();
    1688             :     if (pc->sc()->isGlobalContext() && scope == &pc->varScope())
    1689             :         return true;
    1690           0 : 
    1691             :     return usedNames.noteUse(context, name, pc->scriptId(), scope->id());
    1692             : }
    1693             : 
    1694           0 : bool
    1695             : ParserBase::hasUsedName(HandlePropertyName name)
    1696           0 : {
    1697           0 :     if (UsedNamePtr p = usedNames.lookup(name))
    1698           0 :         return p->value().isUsedInScript(pc->scriptId());
    1699             :     return false;
    1700             : }
    1701             : 
    1702             : template <class ParseHandler>
    1703           0 : bool
    1704             : PerHandlerParser<ParseHandler>::propagateFreeNamesAndMarkClosedOverBindings(ParseContext::Scope& scope)
    1705             : {
    1706             :     // Now that we have all the declared names in the scope, check which
    1707           0 :     // functions should exhibit Annex B semantics.
    1708             :     if (!scope.propagateAndMarkAnnexBFunctionBoxes(pc))
    1709             :         return false;
    1710           0 : 
    1711             :     if (handler.canSkipLazyClosedOverBindings()) {
    1712             :         // Scopes are nullptr-delimited in the LazyScript closed over bindings
    1713           0 :         // array.
    1714           0 :         while (JSAtom* name = handler.nextLazyClosedOverBinding())
    1715             :             scope.lookupDeclaredName(name)->value()->setClosedOver();
    1716             :         return true;
    1717             :     }
    1718           0 : 
    1719           0 :     bool isSyntaxParser = mozilla::IsSame<ParseHandler, SyntaxParseHandler>::value;
    1720           0 :     uint32_t scriptId = pc->scriptId();
    1721           0 :     uint32_t scopeId = scope.id();
    1722           0 :     for (BindingIter bi = scope.bindings(pc); bi; bi++) {
    1723             :         if (UsedNamePtr p = usedNames.lookup(bi.name())) {
    1724           0 :             bool closedOver;
    1725           0 :             p->value().noteBoundInScope(scriptId, scopeId, &closedOver);
    1726           0 :             if (closedOver) {
    1727             :                 bi.setClosedOver();
    1728           0 : 
    1729           0 :                 if (isSyntaxParser && !pc->closedOverBindingsForLazy().append(bi.name())) {
    1730           0 :                     ReportOutOfMemory(context);
    1731             :                     return false;
    1732             :                 }
    1733             :             }
    1734             :         }
    1735             :     }
    1736             : 
    1737           0 :     // Append a nullptr to denote end-of-scope.
    1738           0 :     if (isSyntaxParser && !pc->closedOverBindingsForLazy().append(nullptr)) {
    1739           0 :         ReportOutOfMemory(context);
    1740             :         return false;
    1741             :     }
    1742             : 
    1743             :     return true;
    1744             : }
    1745             : 
    1746             : template <typename CharT>
    1747           0 : bool
    1748             : Parser<FullParseHandler, CharT>::checkStatementsEOF()
    1749             : {
    1750             :     // This is designed to be paired with parsing a statement list at the top
    1751             :     // level.
    1752             :     //
    1753             :     // The statementList() call breaks on TokenKind::Rc, so make sure we've
    1754             :     // reached EOF here.
    1755           0 :     TokenKind tt;
    1756             :     if (!tokenStream.peekToken(&tt, TokenStream::Operand))
    1757           0 :         return false;
    1758           0 :     if (tt != TokenKind::Eof) {
    1759           0 :         error(JSMSG_UNEXPECTED_TOKEN, "expression", TokenKindToDesc(tt));
    1760             :         return false;
    1761             :     }
    1762             :     return true;
    1763             : }
    1764             : 
    1765             : template <typename Scope>
    1766           0 : typename Scope::Data*
    1767             : NewEmptyBindingData(JSContext* cx, LifoAlloc& alloc, uint32_t numBindings)
    1768             : {
    1769           0 :     using Data = typename Scope::Data;
    1770           0 :     size_t allocSize = SizeOfData<typename Scope::Data>(numBindings);
    1771           0 :     auto* bindings = alloc.allocInSize<Data>(allocSize, numBindings);
    1772           0 :     if (!bindings)
    1773           0 :         ReportOutOfMemory(cx);
    1774             :     return bindings;
    1775             : }
    1776             : 
    1777             : /**
    1778             :  * Copy-construct |BindingName|s from |bindings| into |cursor|, then return
    1779             :  * the location one past the newly-constructed |BindingName|s.
    1780             :  */
    1781           0 : static MOZ_MUST_USE BindingName*
    1782             : FreshlyInitializeBindings(BindingName* cursor, const Vector<BindingName>& bindings)
    1783           0 : {
    1784           0 :     return std::uninitialized_copy(bindings.begin(), bindings.end(), cursor);
    1785           0 : }
    1786             : 
    1787             : Maybe<GlobalScope::Data*>
    1788             : NewGlobalScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc, ParseContext* pc)
    1789           0 : {
    1790             :     Vector<BindingName> vars(context);
    1791        1170 :     Vector<BindingName> lets(context);
    1792           0 :     Vector<BindingName> consts(context);
    1793           0 : 
    1794             :     bool allBindingsClosedOver = pc->sc()->allBindingsClosedOver();
    1795           0 :     for (BindingIter bi = scope.bindings(pc); bi; bi++) {
    1796        9012 :         bool closedOver = allBindingsClosedOver || bi.closedOver();
    1797           0 : 
    1798             :         switch (bi.kind()) {
    1799           0 :           case BindingKind::Var: {
    1800             :             bool isTopLevelFunction = bi.declarationKind() == DeclarationKind::BodyLevelFunction;
    1801        2196 :             BindingName binding(bi.name(), closedOver, isTopLevelFunction);
    1802           0 :             if (!vars.append(binding))
    1803           0 :                 return Nothing();
    1804           0 :             break;
    1805        2196 :           }
    1806             :           case BindingKind::Let: {
    1807             :             BindingName binding(bi.name(), closedOver);
    1808         480 :             if (!lets.append(binding))
    1809         240 :                 return Nothing();
    1810           0 :             break;
    1811           0 :           }
    1812             :           case BindingKind::Const: {
    1813             :             BindingName binding(bi.name(), closedOver);
    1814        2970 :             if (!consts.append(binding))
    1815           0 :                 return Nothing();
    1816           0 :             break;
    1817        1485 :           }
    1818             :           default:
    1819             :             MOZ_CRASH("Bad global scope BindingKind");
    1820           0 :         }
    1821             :     }
    1822             : 
    1823             :     GlobalScope::Data* bindings = nullptr;
    1824           0 :     uint32_t numBindings = vars.length() + lets.length() + consts.length();
    1825         390 : 
    1826             :     if (numBindings > 0) {
    1827           0 :         bindings = NewEmptyBindingData<GlobalScope>(context, alloc, numBindings);
    1828           0 :         if (!bindings)
    1829         278 :             return Nothing();
    1830             : 
    1831             :         // The ordering here is important. See comments in GlobalScope.
    1832             :         BindingName* start = bindings->trailingNames.start();
    1833           0 :         BindingName* cursor = start;
    1834         278 : 
    1835             :         cursor = FreshlyInitializeBindings(cursor, vars);
    1836         278 : 
    1837             :         bindings->letStart = cursor - start;
    1838           0 :         cursor = FreshlyInitializeBindings(cursor, lets);
    1839         278 : 
    1840             :         bindings->constStart = cursor - start;
    1841           0 :         cursor = FreshlyInitializeBindings(cursor, consts);
    1842         278 : 
    1843             :         bindings->length = numBindings;
    1844           0 :     }
    1845             : 
    1846             :     return Some(bindings);
    1847             : }
    1848             : 
    1849             : Maybe<GlobalScope::Data*>
    1850             : ParserBase::newGlobalScopeData(ParseContext::Scope& scope)
    1851           0 : {
    1852             :     return NewGlobalScopeData(context, scope, alloc, pc);
    1853           1 : }
    1854             : 
    1855             : Maybe<ModuleScope::Data*>
    1856             : NewModuleScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc, ParseContext* pc)
    1857           0 : {
    1858             :     Vector<BindingName> imports(context);
    1859           0 :     Vector<BindingName> vars(context);
    1860           0 :     Vector<BindingName> lets(context);
    1861           0 :     Vector<BindingName> consts(context);
    1862           0 : 
    1863             :     bool allBindingsClosedOver = pc->sc()->allBindingsClosedOver();
    1864           0 :     for (BindingIter bi = scope.bindings(pc); bi; bi++) {
    1865           0 :         // Imports are indirect bindings and must not be given known slots.
    1866             :         BindingName binding(bi.name(), (allBindingsClosedOver || bi.closedOver()) &&
    1867           0 :                                        bi.kind() != BindingKind::Import);
    1868           0 :         switch (bi.kind()) {
    1869           0 :           case BindingKind::Import:
    1870             :             if (!imports.append(binding))
    1871           0 :                 return Nothing();
    1872             :             break;
    1873             :           case BindingKind::Var:
    1874             :             if (!vars.append(binding))
    1875           0 :                 return Nothing();
    1876             :             break;
    1877             :           case BindingKind::Let:
    1878             :             if (!lets.append(binding))
    1879           0 :                 return Nothing();
    1880             :             break;
    1881             :           case BindingKind::Const:
    1882             :             if (!consts.append(binding))
    1883           0 :                 return Nothing();
    1884             :             break;
    1885             :           default:
    1886             :             MOZ_CRASH("Bad module scope BindingKind");
    1887           0 :         }
    1888             :     }
    1889             : 
    1890             :     ModuleScope::Data* bindings = nullptr;
    1891           0 :     uint32_t numBindings = imports.length() + vars.length() + lets.length() + consts.length();
    1892           0 : 
    1893             :     if (numBindings > 0) {
    1894           0 :         bindings = NewEmptyBindingData<ModuleScope>(context, alloc, numBindings);
    1895           0 :         if (!bindings)
    1896           0 :             return Nothing();
    1897             : 
    1898             :         // The ordering here is important. See comments in ModuleScope.
    1899             :         BindingName* start = bindings->trailingNames.start();
    1900           0 :         BindingName* cursor = start;
    1901           0 : 
    1902             :         cursor = FreshlyInitializeBindings(cursor, imports);
    1903           0 : 
    1904             :         bindings->varStart = cursor - start;
    1905           0 :         cursor = FreshlyInitializeBindings(cursor, vars);
    1906           0 : 
    1907             :         bindings->letStart = cursor - start;
    1908           0 :         cursor = FreshlyInitializeBindings(cursor, lets);
    1909           0 : 
    1910             :         bindings->constStart = cursor - start;
    1911           0 :         cursor = FreshlyInitializeBindings(cursor, consts);
    1912           0 : 
    1913             :         bindings->length = numBindings;
    1914           0 :     }
    1915             : 
    1916             :     return Some(bindings);
    1917             : }
    1918             : 
    1919             : Maybe<ModuleScope::Data*>
    1920             : ParserBase::newModuleScopeData(ParseContext::Scope& scope)
    1921           0 : {
    1922             :     return NewModuleScopeData(context, scope, alloc, pc);
    1923           0 : }
    1924             : 
    1925             : Maybe<EvalScope::Data*>
    1926             : NewEvalScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc, ParseContext* pc)
    1927          20 : {
    1928             :     Vector<BindingName> vars(context);
    1929           0 : 
    1930             :     for (BindingIter bi = scope.bindings(pc); bi; bi++) {
    1931           0 :         // Eval scopes only contain 'var' bindings. Make all bindings aliased
    1932             :         // for now.
    1933             :         MOZ_ASSERT(bi.kind() == BindingKind::Var);
    1934           0 :         bool isTopLevelFunction = bi.declarationKind() == DeclarationKind::BodyLevelFunction;
    1935         158 :         BindingName binding(bi.name(), true, isTopLevelFunction);
    1936         316 :         if (!vars.append(binding))
    1937           0 :             return Nothing();
    1938           0 :     }
    1939             : 
    1940             :     EvalScope::Data* bindings = nullptr;
    1941          20 :     uint32_t numBindings = vars.length();
    1942          20 : 
    1943             :     if (numBindings > 0) {
    1944          20 :         bindings = NewEmptyBindingData<EvalScope>(context, alloc, numBindings);
    1945          17 :         if (!bindings)
    1946          17 :             return Nothing();
    1947             : 
    1948             :         BindingName* start = bindings->trailingNames.start();
    1949           0 :         BindingName* cursor = start;
    1950          17 : 
    1951             :         cursor = FreshlyInitializeBindings(cursor, vars);
    1952           0 : 
    1953             :         bindings->length = numBindings;
    1954          17 :     }
    1955             : 
    1956             :     return Some(bindings);
    1957             : }
    1958             : 
    1959             : Maybe<EvalScope::Data*>
    1960             : ParserBase::newEvalScopeData(ParseContext::Scope& scope)
    1961           0 : {
    1962             :     return NewEvalScopeData(context, scope, alloc, pc);
    1963           0 : }
    1964             : 
    1965             : Maybe<FunctionScope::Data*>
    1966             : NewFunctionScopeData(JSContext* context, ParseContext::Scope& scope, bool hasParameterExprs, LifoAlloc& alloc, ParseContext* pc)
    1967       13057 : {
    1968             :     Vector<BindingName> positionalFormals(context);
    1969       39171 :     Vector<BindingName> formals(context);
    1970       39171 :     Vector<BindingName> vars(context);
    1971       39171 : 
    1972             :     bool allBindingsClosedOver = pc->sc()->allBindingsClosedOver();
    1973           1 :     bool hasDuplicateParams = pc->functionBox()->hasDuplicateParameters;
    1974       26114 : 
    1975             :     // Positional parameter names must be added in order of appearance as they are
    1976             :     // referenced using argument slots.
    1977             :     for (size_t i = 0; i < pc->positionalFormalParameterNames().length(); i++) {
    1978       53174 :         JSAtom* name = pc->positionalFormalParameterNames()[i];
    1979           0 : 
    1980             :         BindingName bindName;
    1981           0 :         if (name) {
    1982           0 :             DeclaredNamePtr p = scope.lookupDeclaredName(name);
    1983           0 : 
    1984             :             // Do not consider any positional formal parameters closed over if
    1985             :             // there are parameter defaults. It is the binding in the defaults
    1986             :             // scope that is closed over instead.
    1987             :             bool closedOver = allBindingsClosedOver ||
    1988       26087 :                               (p && p->value()->closedOver());
    1989       25330 : 
    1990             :             // If the parameter name has duplicates, only the final parameter
    1991             :             // name should be on the environment, as otherwise the environment
    1992             :             // object would have multiple, same-named properties.
    1993             :             if (hasDuplicateParams) {
    1994           0 :                 for (size_t j = pc->positionalFormalParameterNames().length() - 1; j > i; j--) {
    1995           0 :                     if (pc->positionalFormalParameterNames()[j] == name) {
    1996           0 :                         closedOver = false;
    1997             :                         break;
    1998             :                     }
    1999             :                 }
    2000             :             }
    2001             : 
    2002             :             bindName = BindingName(name, closedOver);
    2003       26844 :         }
    2004             : 
    2005             :         if (!positionalFormals.append(bindName))
    2006           0 :             return Nothing();
    2007           0 :     }
    2008             : 
    2009             :     for (BindingIter bi = scope.bindings(pc); bi; bi++) {
    2010      100095 :         BindingName binding(bi.name(), allBindingsClosedOver || bi.closedOver());
    2011       60924 :         switch (bi.kind()) {
    2012       30462 :           case BindingKind::FormalParameter:
    2013             :             // Positional parameter names are already handled above.
    2014             :             if (bi.declarationKind() == DeclarationKind::FormalParameter) {
    2015           0 :                 if (!formals.append(binding))
    2016         234 :                     return Nothing();
    2017             :             }
    2018             :             break;
    2019             :           case BindingKind::Var:
    2020             :             // The only vars in the function scope when there are parameter
    2021             :             // exprs, which induces a separate var environment, should be the
    2022             :             // special bindings.
    2023             :             MOZ_ASSERT_IF(hasParameterExprs, FunctionScope::isSpecialName(context, bi.name()));
    2024           0 :             if (!vars.append(binding))
    2025        9925 :                 return Nothing();
    2026             :             break;
    2027             :           default:
    2028             :             break;
    2029             :         }
    2030             :     }
    2031             : 
    2032             :     FunctionScope::Data* bindings = nullptr;
    2033       13057 :     uint32_t numBindings = positionalFormals.length() + formals.length() + vars.length();
    2034       13057 : 
    2035             :     if (numBindings > 0) {
    2036           0 :         bindings = NewEmptyBindingData<FunctionScope>(context, alloc, numBindings);
    2037           0 :         if (!bindings)
    2038       11253 :             return Nothing();
    2039             : 
    2040             :         // The ordering here is important. See comments in FunctionScope.
    2041             :         BindingName* start = bindings->trailingNames.start();
    2042       22506 :         BindingName* cursor = start;
    2043       11253 : 
    2044             :         cursor = FreshlyInitializeBindings(cursor, positionalFormals);
    2045           0 : 
    2046             :         bindings->nonPositionalFormalStart = cursor - start;
    2047       11253 :         cursor = FreshlyInitializeBindings(cursor, formals);
    2048           0 : 
    2049             :         bindings->varStart = cursor - start;
    2050           0 :         cursor = FreshlyInitializeBindings(cursor, vars);
    2051       11253 : 
    2052             :         bindings->length = numBindings;
    2053       11253 :     }
    2054             : 
    2055             :     return Some(bindings);
    2056             : }
    2057             : 
    2058             : Maybe<FunctionScope::Data*>
    2059             : ParserBase::newFunctionScopeData(ParseContext::Scope& scope, bool hasParameterExprs)
    2060           0 : {
    2061             :     return NewFunctionScopeData(context, scope, hasParameterExprs, alloc, pc);
    2062           0 : }
    2063             : 
    2064             : Maybe<VarScope::Data*>
    2065             : NewVarScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc, ParseContext* pc)
    2066         473 : {
    2067             :     Vector<BindingName> vars(context);
    2068        1419 : 
    2069             :     bool allBindingsClosedOver = pc->sc()->allBindingsClosedOver();
    2070         473 : 
    2071             :     for (BindingIter bi = scope.bindings(pc); bi; bi++) {
    2072           1 :         if (bi.kind() == BindingKind::Var) {
    2073         746 :             BindingName binding(bi.name(), allBindingsClosedOver || bi.closedOver());
    2074           0 :             if (!vars.append(binding))
    2075         116 :                 return Nothing();
    2076           0 :         }
    2077             :     }
    2078             : 
    2079             :     VarScope::Data* bindings = nullptr;
    2080           0 :     uint32_t numBindings = vars.length();
    2081         473 : 
    2082             :     if (numBindings > 0) {
    2083         473 :         bindings = NewEmptyBindingData<VarScope>(context, alloc, numBindings);
    2084           0 :         if (!bindings)
    2085           0 :             return Nothing();
    2086             : 
    2087             :         // The ordering here is important. See comments in FunctionScope.
    2088             :         BindingName* start = bindings->trailingNames.start();
    2089          52 :         BindingName* cursor = start;
    2090          26 : 
    2091             :         cursor = FreshlyInitializeBindings(cursor, vars);
    2092           0 : 
    2093             :         bindings->length = numBindings;
    2094          26 :     }
    2095             : 
    2096             :     return Some(bindings);
    2097             : }
    2098             : 
    2099             : Maybe<VarScope::Data*>
    2100             : ParserBase::newVarScopeData(ParseContext::Scope& scope)
    2101           0 : {
    2102             :     return NewVarScopeData(context, scope, alloc, pc);
    2103         473 : }
    2104             : 
    2105             : Maybe<LexicalScope::Data*>
    2106             : NewLexicalScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc, ParseContext* pc)
    2107       33654 : {
    2108             :     Vector<BindingName> lets(context);
    2109      100962 :     Vector<BindingName> consts(context);
    2110      100962 : 
    2111             :     // Unlike other scopes with bindings which are body-level, it is unknown
    2112             :     // if pc->sc()->allBindingsClosedOver() is correct at the time of
    2113             :     // finishing parsing a lexical scope.
    2114             :     //
    2115             :     // Instead, pc->sc()->allBindingsClosedOver() is checked in
    2116             :     // EmitterScope::enterLexical. Also see comment there.
    2117             :     for (BindingIter bi = scope.bindings(pc); bi; bi++) {
    2118      175317 :         BindingName binding(bi.name(), bi.closedOver());
    2119           0 :         switch (bi.kind()) {
    2120       37178 :           case BindingKind::Let:
    2121             :             if (!lets.append(binding))
    2122           0 :                 return Nothing();
    2123             :             break;
    2124             :           case BindingKind::Const:
    2125             :             if (!consts.append(binding))
    2126        2788 :                 return Nothing();
    2127             :             break;
    2128             :           default:
    2129             :             break;
    2130             :         }
    2131             :     }
    2132             : 
    2133             :     LexicalScope::Data* bindings = nullptr;
    2134           0 :     uint32_t numBindings = lets.length() + consts.length();
    2135       33654 : 
    2136             :     if (numBindings > 0) {
    2137       33654 :         bindings = NewEmptyBindingData<LexicalScope>(context, alloc, numBindings);
    2138           0 :         if (!bindings)
    2139        9629 :             return Nothing();
    2140             : 
    2141             :         // The ordering here is important. See comments in LexicalScope.
    2142             :         BindingName* cursor = bindings->trailingNames.start();
    2143       19258 :         BindingName* start = cursor;
    2144        9629 : 
    2145             :         cursor = FreshlyInitializeBindings(cursor, lets);
    2146           0 : 
    2147             :         bindings->constStart = cursor - start;
    2148        9629 :         cursor = FreshlyInitializeBindings(cursor, consts);
    2149           0 : 
    2150             :         bindings->length = numBindings;
    2151           0 :     }
    2152             : 
    2153             :     return Some(bindings);
    2154             : }
    2155             : 
    2156             : Maybe<LexicalScope::Data*>
    2157             : ParserBase::newLexicalScopeData(ParseContext::Scope& scope)
    2158           0 : {
    2159             :     return NewLexicalScopeData(context, scope, alloc, pc);
    2160           0 : }
    2161             : 
    2162             : template <>
    2163             : SyntaxParseHandler::Node
    2164             : PerHandlerParser<SyntaxParseHandler>::finishLexicalScope(ParseContext::Scope& scope, Node body)
    2165           0 : {
    2166             :     if (!propagateFreeNamesAndMarkClosedOverBindings(scope))
    2167           0 :         return null();
    2168             : 
    2169             :     return body;
    2170           0 : }
    2171             : 
    2172             : template <>
    2173             : ParseNode*
    2174             : PerHandlerParser<FullParseHandler>::finishLexicalScope(ParseContext::Scope& scope, ParseNode* body)
    2175       32421 : {
    2176             :     if (!propagateFreeNamesAndMarkClosedOverBindings(scope))
    2177           1 :         return nullptr;
    2178             : 
    2179             :     Maybe<LexicalScope::Data*> bindings = newLexicalScopeData(scope);
    2180       64842 :     if (!bindings)
    2181       32421 :         return nullptr;
    2182             : 
    2183             :     return handler.newLexicalScope(*bindings, body);
    2184       64842 : }
    2185             : 
    2186             : template <typename CharT>
    2187             : ParseNode*
    2188             : Parser<FullParseHandler, CharT>::evalBody(EvalSharedContext* evalsc)
    2189           0 : {
    2190             :     SourceParseContext evalpc(this, evalsc, /* newDirectives = */ nullptr);
    2191          60 :     if (!evalpc.init())
    2192           0 :         return nullptr;
    2193             : 
    2194             :     ParseContext::VarScope varScope(this);
    2195          40 :     if (!varScope.init(pc))
    2196           0 :         return nullptr;
    2197             : 
    2198             :     ParseNode* body;
    2199             :     {
    2200             :         // All evals have an implicit non-extensible lexical scope.
    2201             :         ParseContext::Scope lexicalScope(this);
    2202          40 :         if (!lexicalScope.init(pc))
    2203           0 :             return nullptr;
    2204           0 : 
    2205             :         body = statementList(YieldIsName);
    2206          20 :         if (!body)
    2207           0 :             return nullptr;
    2208             : 
    2209             :         if (!checkStatementsEOF())
    2210          20 :             return nullptr;
    2211             : 
    2212             :         body = finishLexicalScope(lexicalScope, body);
    2213          20 :         if (!body)
    2214           0 :             return nullptr;
    2215             :     }
    2216             : 
    2217             : #ifdef DEBUG
    2218             :     if (evalpc.superScopeNeedsHomeObject() && evalsc->compilationEnclosingScope()) {
    2219           0 :         // If superScopeNeedsHomeObject_ is set and we are an entry-point
    2220             :         // ParseContext, then we must be emitting an eval script, and the
    2221             :         // outer function must already be marked as needing a home object
    2222             :         // since it contains an eval.
    2223             :         ScopeIter si(evalsc->compilationEnclosingScope());
    2224           0 :         for (; si; si++) {
    2225           0 :             if (si.kind() == ScopeKind::Function) {
    2226           0 :                 JSFunction* fun = si.scope()->as<FunctionScope>().canonicalFunction();
    2227           0 :                 if (fun->isArrow())
    2228           0 :                     continue;
    2229             :                 MOZ_ASSERT(fun->allowSuperProperty());
    2230           0 :                 MOZ_ASSERT(fun->nonLazyScript()->needsHomeObject());
    2231           0 :                 break;
    2232             :             }
    2233             :         }
    2234             :         MOZ_ASSERT(!si.done(),
    2235           0 :                    "Eval must have found an enclosing function box scope that allows super.property");
    2236             :     }
    2237             : #endif
    2238             : 
    2239             :     if (!FoldConstants(context, &body, this))
    2240           0 :         return nullptr;
    2241             : 
    2242             :     if (!this->setSourceMapInfo())
    2243           0 :         return nullptr;
    2244             : 
    2245             :     // For eval scripts, since all bindings are automatically considered
    2246             :     // closed over, we don't need to call propagateFreeNamesAndMarkClosed-
    2247             :     // OverBindings. However, Annex B.3.3 functions still need to be marked.
    2248             :     if (!varScope.propagateAndMarkAnnexBFunctionBoxes(pc))
    2249          20 :         return nullptr;
    2250             : 
    2251             :     Maybe<EvalScope::Data*> bindings = newEvalScopeData(pc->varScope());
    2252           0 :     if (!bindings)
    2253          20 :         return nullptr;
    2254             :     evalsc->bindings = *bindings;
    2255           0 : 
    2256             :     return body;
    2257          20 : }
    2258             : 
    2259             : template <typename CharT>
    2260             : ParseNode*
    2261             : Parser<FullParseHandler, CharT>::globalBody(GlobalSharedContext* globalsc)
    2262         390 : {
    2263             :     SourceParseContext globalpc(this, globalsc, /* newDirectives = */ nullptr);
    2264           0 :     if (!globalpc.init())
    2265           0 :         return nullptr;
    2266             : 
    2267             :     ParseContext::VarScope varScope(this);
    2268         780 :     if (!varScope.init(pc))
    2269           0 :         return nullptr;
    2270             : 
    2271             :     ParseNode* body = statementList(YieldIsName);
    2272         390 :     if (!body)
    2273         390 :         return nullptr;
    2274             : 
    2275             :     if (!checkStatementsEOF())
    2276           0 :         return nullptr;
    2277             : 
    2278             :     if (!FoldConstants(context, &body, this))
    2279         390 :         return nullptr;
    2280             : 
    2281             :     if (!this->setSourceMapInfo())
    2282         390 :         return nullptr;
    2283             : 
    2284             :     // For global scripts, whether bindings are closed over or not doesn't
    2285             :     // matter, so no need to call propagateFreeNamesAndMarkClosedOver-
    2286             :     // Bindings. However, Annex B.3.3 functions still need to be marked.
    2287             :     if (!varScope.propagateAndMarkAnnexBFunctionBoxes(pc))
    2288           0 :         return nullptr;
    2289             : 
    2290             :     Maybe<GlobalScope::Data*> bindings = newGlobalScopeData(pc->varScope());
    2291           0 :     if (!bindings)
    2292         390 :         return nullptr;
    2293             :     globalsc->bindings = *bindings;
    2294           0 : 
    2295             :     return body;
    2296         390 : }
    2297             : 
    2298             : template <typename CharT>
    2299             : ParseNode*
    2300             : Parser<FullParseHandler, CharT>::moduleBody(ModuleSharedContext* modulesc)
    2301           0 : {
    2302             :     MOZ_ASSERT(checkOptionsCalled);
    2303           0 : 
    2304             :     SourceParseContext modulepc(this, modulesc, nullptr);
    2305           0 :     if (!modulepc.init())
    2306           0 :         return null();
    2307             : 
    2308             :     ParseContext::VarScope varScope(this);
    2309           0 :     if (!varScope.init(pc))
    2310           0 :         return nullptr;
    2311             : 
    2312             :     Node mn = handler.newModule(pos());
    2313           0 :     if (!mn)
    2314           0 :         return null();
    2315             : 
    2316             :     AutoAwaitIsKeyword<FullParseHandler, CharT> awaitIsKeyword(this, AwaitIsModuleKeyword);
    2317           0 :     ParseNode* pn = statementList(YieldIsName);
    2318           0 :     if (!pn)
    2319           0 :         return null();
    2320             : 
    2321             :     MOZ_ASSERT(pn->isKind(ParseNodeKind::StatementList));
    2322           0 :     mn->pn_body = pn;
    2323           0 : 
    2324             :     TokenKind tt;
    2325             :     if (!tokenStream.getToken(&tt, TokenStream::Operand))
    2326           0 :         return null();
    2327             :     if (tt != TokenKind::Eof) {
    2328           0 :         error(JSMSG_GARBAGE_AFTER_INPUT, "module", TokenKindToDesc(tt));
    2329           0 :         return null();
    2330           0 :     }
    2331             : 
    2332             :     if (!modulesc->builder.buildTables())
    2333           0 :         return null();
    2334             : 
    2335             :     // Check exported local bindings exist and mark them as closed over.
    2336             :     for (auto entry : modulesc->builder.localExportEntries()) {
    2337           0 :         JSAtom* name = entry->localName();
    2338           0 :         MOZ_ASSERT(name);
    2339           0 : 
    2340             :         DeclaredNamePtr p = modulepc.varScope().lookupDeclaredName(name);
    2341           0 :         if (!p) {
    2342           0 :             JSAutoByteString str;
    2343           0 :             if (!AtomToPrintableString(context, name, &str))
    2344           0 :                 return null();
    2345             : 
    2346             :             errorAt(TokenStream::NoOffset, JSMSG_MISSING_EXPORT, str.ptr());
    2347           0 :             return null();
    2348           0 :         }
    2349             : 
    2350             :         p->value()->setClosedOver();
    2351           0 :     }
    2352             : 
    2353             :     if (!FoldConstants(context, &pn, this))
    2354           0 :         return null();
    2355             : 
    2356             :     if (!this->setSourceMapInfo())
    2357           0 :         return null();
    2358             : 
    2359             :     if (!propagateFreeNamesAndMarkClosedOverBindings(modulepc.varScope()))
    2360           0 :         return null();
    2361             : 
    2362             :     Maybe<ModuleScope::Data*> bindings = newModuleScopeData(modulepc.varScope());
    2363           0 :     if (!bindings)
    2364           0 :         return nullptr;
    2365             : 
    2366             :     modulesc->bindings = *bindings;
    2367           0 :     return mn;
    2368           0 : }
    2369             : 
    2370             : template <typename CharT>
    2371             : SyntaxParseHandler::Node
    2372             : Parser<SyntaxParseHandler, CharT>::moduleBody(ModuleSharedContext* modulesc)
    2373           0 : {
    2374             :     MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
    2375           0 :     return SyntaxParseHandler::NodeFailure;
    2376           0 : }
    2377             : 
    2378             : bool
    2379             : ParserBase::hasUsedFunctionSpecialName(HandlePropertyName name)
    2380           0 : {
    2381             :     MOZ_ASSERT(name == context->names().arguments || name == context->names().dotThis);
    2382      117117 :     return hasUsedName(name) || pc->functionBox()->bindingsAccessedDynamically();
    2383       50852 : }
    2384             : 
    2385             : template <class ParseHandler>
    2386             : bool
    2387             : PerHandlerParser<ParseHandler>::declareFunctionThis()
    2388           1 : {
    2389             :     // The asm.js validator does all its own symbol-table management so, as an
    2390             :     // optimization, avoid doing any work here.
    2391             :     if (pc->useAsmOrInsideUseAsm())
    2392           0 :         return true;
    2393             : 
    2394             :     // Derived class constructors emit JSOP_CHECKRETURN, which requires
    2395             :     // '.this' to be bound.
    2396             :     FunctionBox* funbox = pc->functionBox();
    2397       21294 :     HandlePropertyName dotThis = context->names().dotThis;
    2398       31941 : 
    2399             :     bool declareThis;
    2400             :     if (handler.canSkipLazyClosedOverBindings())
    2401       21294 :         declareThis = funbox->function()->lazyScript()->hasThisBinding();
    2402           0 :     else
    2403             :         declareThis = hasUsedFunctionSpecialName(dotThis) || funbox->isDerivedClassConstructor();
    2404           0 : 
    2405             :     if (declareThis) {
    2406       10647 :         ParseContext::Scope& funScope = pc->functionScope();
    2407        6390 :         AddDeclaredNamePtr p = funScope.lookupDeclaredNameForAdd(dotThis);
    2408       12780 :         MOZ_ASSERT(!p);
    2409           0 :         if (!funScope.addDeclaredName(pc, p, dotThis, DeclarationKind::Var,
    2410           0 :                                       DeclaredNameInfo::npos))
    2411             :         {
    2412             :             return false;
    2413           0 :         }
    2414             :         funbox->setHasThisBinding();
    2415        6390 :     }
    2416             : 
    2417             :     return true;
    2418             : }
    2419             : 
    2420             : template <class ParseHandler>
    2421             : typename ParseHandler::Node
    2422             : PerHandlerParser<ParseHandler>::newInternalDotName(HandlePropertyName name)
    2423       23728 : {
    2424             :     Node nameNode = newName(name);
    2425           0 :     if (!nameNode)
    2426       23728 :         return null();
    2427             :     if (!noteUsedName(name))
    2428       23728 :         return null();
    2429             :     return nameNode;
    2430       23728 : }
    2431             : 
    2432             : template <class ParseHandler>
    2433             : typename ParseHandler::Node
    2434             : PerHandlerParser<ParseHandler>::newThisName()
    2435           0 : {
    2436             :     return newInternalDotName(context->names().dotThis);
    2437           0 : }
    2438             : 
    2439             : template <class ParseHandler>
    2440             : typename ParseHandler::Node
    2441             : PerHandlerParser<ParseHandler>::newDotGeneratorName()
    2442           0 : {
    2443             :     return newInternalDotName(context->names().dotGenerator);
    2444        2187 : }
    2445             : 
    2446             : bool
    2447             : ParserBase::declareDotGeneratorName()
    2448         729 : {
    2449             :     // The special '.generator' binding must be on the function scope, as
    2450             :     // generators expect to find it on the CallObject.
    2451             :     ParseContext::Scope& funScope = pc->functionScope();
    2452         729 :     HandlePropertyName dotGenerator = context->names().dotGenerator;
    2453        2187 :     AddDeclaredNamePtr p = funScope.lookupDeclaredNameForAdd(dotGenerator);
    2454           0 :     if (!p && !funScope.addDeclaredName(pc, p, dotGenerator, DeclarationKind::Var,
    2455        1458 :                                         DeclaredNameInfo::npos))
    2456           0 :     {
    2457             :         return false;
    2458             :     }
    2459             :     return true;
    2460           0 : }
    2461             : 
    2462             : template <class ParseHandler>
    2463             : bool
    2464             : PerHandlerParser<ParseHandler>::finishFunctionScopes(bool isStandaloneFunction)
    2465           0 : {
    2466             :     FunctionBox* funbox = pc->functionBox();
    2467           0 : 
    2468             :     if (funbox->hasParameterExprs) {
    2469       13057 :         if (!propagateFreeNamesAndMarkClosedOverBindings(pc->functionScope()))
    2470         473 :             return false;
    2471             :     }
    2472             : 
    2473             :     if (funbox->function()->isNamedLambda() && !isStandaloneFunction) {
    2474       26114 :         if (!propagateFreeNamesAndMarkClosedOverBindings(pc->namedLambdaScope()))
    2475        1233 :             return false;
    2476             :     }
    2477             : 
    2478             :     return true;
    2479             : }
    2480             : 
    2481             : template <>
    2482             : bool
    2483             : PerHandlerParser<FullParseHandler>::finishFunction(bool isStandaloneFunction /* = false */)
    2484       13057 : {
    2485             :     if (!finishFunctionScopes(isStandaloneFunction))
    2486           0 :         return false;
    2487             : 
    2488             :     FunctionBox* funbox = pc->functionBox();
    2489       26114 :     bool hasParameterExprs = funbox->hasParameterExprs;
    2490       13057 : 
    2491             :     if (hasParameterExprs) {
    2492       13057 :         Maybe<VarScope::Data*> bindings = newVarScopeData(pc->varScope());
    2493        1419 :         if (!bindings)
    2494         473 :             return false;
    2495           0 :         funbox->extraVarScopeBindings().set(*bindings);
    2496           0 :     }
    2497             : 
    2498             :     {
    2499             :         Maybe<FunctionScope::Data*> bindings = newFunctionScopeData(pc->functionScope(),
    2500       13057 :                                                                     hasParameterExprs);
    2501           0 :         if (!bindings)
    2502           0 :             return false;
    2503           0 :         funbox->functionScopeBindings().set(*bindings);
    2504           0 :     }
    2505             : 
    2506             :     if (funbox->function()->isNamedLambda() && !isStandaloneFunction) {
    2507           1 :         Maybe<LexicalScope::Data*> bindings = newLexicalScopeData(pc->namedLambdaScope());
    2508           0 :         if (!bindings)
    2509        1233 :             return false;
    2510           0 :         funbox->namedLambdaBindings().set(*bindings);
    2511        2466 :     }
    2512             : 
    2513             :     return true;
    2514             : }
    2515             : 
    2516             : template <>
    2517             : bool
    2518             : PerHandlerParser<SyntaxParseHandler>::finishFunction(bool isStandaloneFunction /* = false */)
    2519           0 : {
    2520             :     // The LazyScript for a lazily parsed function needs to know its set of
    2521             :     // free variables and inner functions so that when it is fully parsed, we
    2522             :     // can skip over any already syntax parsed inner functions and still
    2523             :     // retain correct scope information.
    2524             : 
    2525             :     if (!finishFunctionScopes(isStandaloneFunction))
    2526           0 :         return false;
    2527             : 
    2528             :     // There are too many bindings or inner functions to be saved into the
    2529             :     // LazyScript. Do a full parse.
    2530             :     if (pc->closedOverBindingsForLazy().length() >= LazyScript::NumClosedOverBindingsLimit ||
    2531           0 :         pc->innerFunctionsForLazy.length() >= LazyScript::NumInnerFunctionsLimit)
    2532           0 :     {
    2533             :         MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
    2534           0 :         return false;
    2535           0 :     }
    2536             : 
    2537             :     FunctionBox* funbox = pc->functionBox();
    2538           0 :     RootedFunction fun(context, funbox->function());
    2539           0 :     LazyScript* lazy = LazyScript::Create(context, fun, sourceObject,
    2540           0 :                                           pc->closedOverBindingsForLazy(),
    2541           0 :                                           pc->innerFunctionsForLazy,
    2542           0 :                                           funbox->bufStart, funbox->bufEnd,
    2543             :                                           funbox->toStringStart,
    2544             :                                           funbox->startLine, funbox->startColumn,
    2545             :                                           parseGoal());
    2546           0 :     if (!lazy)
    2547           0 :         return false;
    2548             : 
    2549             :     // Flags that need to be copied into the JSScript when we do the full
    2550             :     // parse.
    2551             :     if (pc->sc()->strict())
    2552           0 :         lazy->setStrict();
    2553             :     lazy->setGeneratorKind(funbox->generatorKind());
    2554           0 :     lazy->setAsyncKind(funbox->asyncKind());
    2555           0 :     if (funbox->hasRest())
    2556           0 :         lazy->setHasRest();
    2557             :     if (funbox->isLikelyConstructorWrapper())
    2558           0 :         lazy->setLikelyConstructorWrapper();
    2559             :     if (funbox->isDerivedClassConstructor())
    2560           0 :         lazy->setIsDerivedClassConstructor();
    2561             :     if (funbox->needsHomeObject())
    2562           0 :         lazy->setNeedsHomeObject();
    2563             :     if (funbox->declaredArguments)
    2564           0 :         lazy->setShouldDeclareArguments();
    2565             :     if (funbox->hasThisBinding())
    2566           0 :         lazy->setHasThisBinding();
    2567             : 
    2568             :     // Flags that need to copied back into the parser when we do the full
    2569             :     // parse.
    2570             :     PropagateTransitiveParseFlags(funbox, lazy);
    2571           0 : 
    2572             :     fun->initLazyScript(lazy);
    2573           0 :     return true;
    2574           0 : }
    2575             : 
    2576             : static YieldHandling
    2577             : GetYieldHandling(GeneratorKind generatorKind)
    2578             : {
    2579             :     if (generatorKind == GeneratorKind::NotGenerator)
    2580       23704 :         return YieldIsName;
    2581             :     return YieldIsKeyword;
    2582             : }
    2583             : 
    2584             : static AwaitHandling
    2585             : GetAwaitHandling(FunctionAsyncKind asyncKind)
    2586             : {
    2587             :     if (asyncKind == FunctionAsyncKind::SyncFunction)
    2588       16037 :         return AwaitIsName;
    2589             :     return AwaitIsKeyword;
    2590             : }
    2591             : 
    2592             : template <typename CharT>
    2593             : ParseNode*
    2594             : Parser<FullParseHandler, CharT>::standaloneFunction(HandleFunction fun,
    2595         815 :                                                     HandleScope enclosingScope,
    2596             :                                                     const Maybe<uint32_t>& parameterListEnd,
    2597             :                                                     GeneratorKind generatorKind,
    2598             :                                                     FunctionAsyncKind asyncKind,
    2599             :                                                     Directives inheritedDirectives,
    2600             :                                                     Directives* newDirectives)
    2601             : {
    2602             :     MOZ_ASSERT(checkOptionsCalled);
    2603         815 : 
    2604             :     // Skip prelude.
    2605             :     TokenKind tt;
    2606             :     if (!tokenStream.getToken(&tt, TokenStream::Operand))
    2607           0 :         return null();
    2608             :     if (asyncKind == FunctionAsyncKind::AsyncFunction) {
    2609         815 :         MOZ_ASSERT(tt == TokenKind::Async);
    2610           0 :         if (!tokenStream.getToken(&tt, TokenStream::Operand))
    2611           0 :             return null();
    2612             :     }
    2613             :     MOZ_ASSERT(tt == TokenKind::Function);
    2614         815 : 
    2615             :     if (!tokenStream.getToken(&tt))
    2616         815 :         return null();
    2617             :     if (generatorKind == GeneratorKind::Generator) {
    2618         815 :         MOZ_ASSERT(tt == TokenKind::Mul);
    2619           0 :         if (!tokenStream.getToken(&tt))
    2620           0 :             return null();
    2621             :     }
    2622             : 
    2623             :     // Skip function name, if present.
    2624             :     if (TokenKindIsPossibleIdentifierName(tt)) {
    2625         815 :         MOZ_ASSERT(anyChars.currentName() == fun->explicitName());
    2626           0 :     } else {
    2627             :         MOZ_ASSERT(fun->explicitName() == nullptr);
    2628           0 :         anyChars.ungetToken();
    2629          21 :     }
    2630             : 
    2631             :     Node fn = handler.newFunctionStatement(pos());
    2632           0 :     if (!fn)
    2633         815 :         return null();
    2634             : 
    2635             :     ParseNode* argsbody = handler.newList(ParseNodeKind::ParamsBody, pos());
    2636        1630 :     if (!argsbody)
    2637           0 :         return null();
    2638             :     fn->pn_body = argsbody;
    2639         815 : 
    2640             :     FunctionBox* funbox = newFunctionBox(fn, fun, /* toStringStart = */ 0, inheritedDirectives,
    2641           0 :                                          generatorKind, asyncKind);
    2642         815 :     if (!funbox)
    2643         815 :         return null();
    2644             :     funbox->initStandaloneFunction(enclosingScope);
    2645           0 : 
    2646             :     SourceParseContext funpc(this, funbox, newDirectives);
    2647        1630 :     if (!funpc.init())
    2648           0 :         return null();
    2649             :     funpc.setIsStandaloneFunctionBody();
    2650        1630 : 
    2651             :     YieldHandling yieldHandling = GetYieldHandling(generatorKind);
    2652         815 :     AwaitHandling awaitHandling = GetAwaitHandling(asyncKind);
    2653           0 :     AutoAwaitIsKeyword<FullParseHandler, CharT> awaitIsKeyword(this, awaitHandling);
    2654           0 :     if (!functionFormalParametersAndBody(InAllowed, yieldHandling, &fn, FunctionSyntaxKind::Statement,
    2655           0 :                                          parameterListEnd, /* isStandaloneFunction = */ true))
    2656             :     {
    2657             :         return null();
    2658             :     }
    2659             : 
    2660             :     if (!tokenStream.getToken(&tt, TokenStream::Operand))
    2661         815 :         return null();
    2662             :     if (tt != TokenKind::Eof) {
    2663         815 :         error(JSMSG_GARBAGE_AFTER_INPUT, "function body", TokenKindToDesc(tt));
    2664           0 :         return null();
    2665           0 :     }
    2666             : 
    2667             :     if (!FoldConstants(context, &fn, this))
    2668         815 :         return null();
    2669             : 
    2670             :     if (!this->setSourceMapInfo())
    2671         815 :         return null();
    2672             : 
    2673             :     return fn;
    2674         815 : }
    2675             : 
    2676             : template <class ParseHandler>
    2677             : bool
    2678             : PerHandlerParser<ParseHandler>::declareFunctionArgumentsObject()
    2679       10647 : {
    2680             :     FunctionBox* funbox = pc->functionBox();
    2681       21294 :     ParseContext::Scope& funScope = pc->functionScope();
    2682       10647 :     ParseContext::Scope& varScope = pc->varScope();
    2683           0 : 
    2684             :     bool hasExtraBodyVarScope = &funScope != &varScope;
    2685       10647 : 
    2686             :     // Time to implement the odd semantics of 'arguments'.
    2687             :     HandlePropertyName argumentsName = context->names().arguments;
    2688       31941 : 
    2689             :     bool tryDeclareArguments;
    2690             :     if (handler.canSkipLazyClosedOverBindings())
    2691           0 :         tryDeclareArguments = funbox->function()->lazyScript()->shouldDeclareArguments();
    2692           0 :     else
    2693             :         tryDeclareArguments = hasUsedFunctionSpecialName(argumentsName);
    2694           0 : 
    2695             :     // ES 9.2.12 steps 19 and 20 say formal parameters, lexical bindings,
    2696             :     // and body-level functions named 'arguments' shadow the arguments
    2697             :     // object.
    2698             :     //
    2699             :     // So even if there wasn't a free use of 'arguments' but there is a var
    2700             :     // binding of 'arguments', we still might need the arguments object.
    2701             :     //
    2702             :     // If we have an extra var scope due to parameter expressions and the body
    2703             :     // declared 'var arguments', we still need to declare 'arguments' in the
    2704             :     // function scope.
    2705             :     DeclaredNamePtr p = varScope.lookupDeclaredName(argumentsName);
    2706           0 :     if (p && (p->value()->kind() == DeclarationKind::Var ||
    2707       10647 :               p->value()->kind() == DeclarationKind::ForOfVar))
    2708           0 :     {
    2709             :         if (hasExtraBodyVarScope)
    2710           0 :             tryDeclareArguments = true;
    2711             :         else
    2712             :             funbox->usesArguments = true;
    2713           0 :     }
    2714             : 
    2715             :     if (tryDeclareArguments) {
    2716       10647 :         AddDeclaredNamePtr p = funScope.lookupDeclaredNameForAdd(argumentsName);
    2717         290 :         if (!p) {
    2718           0 :             if (!funScope.addDeclaredName(pc, p, argumentsName, DeclarationKind::Var,
    2719           0 :                                           DeclaredNameInfo::npos))
    2720             :             {
    2721             :                 return false;
    2722           0 :             }
    2723             :             funbox->declaredArguments = true;
    2724         145 :             funbox->usesArguments = true;
    2725           0 :         } else if (hasExtraBodyVarScope) {
    2726           0 :             // Formal parameters shadow the arguments object.
    2727             :             return true;
    2728             :         }
    2729             :     }
    2730             : 
    2731             :     // Compute if we need an arguments object.
    2732             :     if (funbox->usesArguments) {
    2733       10647 :         // There is an 'arguments' binding. Is the arguments object definitely
    2734             :         // needed?
    2735             :         //
    2736             :         // Also see the flags' comments in ContextFlags.
    2737             :         funbox->setArgumentsHasLocalBinding();
    2738           0 : 
    2739             :         // Dynamic scope access destroys all hope of optimization.
    2740             :         if (pc->sc()->bindingsAccessedDynamically())
    2741         290 :             funbox->setDefinitelyNeedsArgsObj();
    2742          20 : 
    2743             :         // If a script contains the debugger statement either directly or
    2744             :         // within an inner function, the arguments object should be created
    2745             :         // eagerly so the Debugger API may observe bindings.
    2746             :         if (pc->sc()->hasDebuggerStatement())
    2747         290 :             funbox->setDefinitelyNeedsArgsObj();
    2748           0 :     }
    2749             : 
    2750             :     return true;
    2751             : }
    2752             : 
    2753             : template <class ParseHandler, typename CharT>
    2754             : typename ParseHandler::Node
    2755             : GeneralParser<ParseHandler, CharT>::functionBody(InHandling inHandling,
    2756       13057 :                                                  YieldHandling yieldHandling,
    2757             :                                                  FunctionSyntaxKind kind, FunctionBodyType type)
    2758             : {
    2759             :     MOZ_ASSERT(pc->isFunctionBox());
    2760           0 : 
    2761             : #ifdef DEBUG
    2762             :     uint32_t startYieldOffset = pc->lastYieldOffset;
    2763       13057 : #endif
    2764             : 
    2765             :     Node pn;
    2766             :     if (type == StatementListBody) {
    2767       13057 :         bool inheritedStrict = pc->sc()->strict();
    2768           0 :         pn = statementList(yieldHandling);
    2769       12017 :         if (!pn)
    2770       12017 :             return null();
    2771             : 
    2772             :         // When we transitioned from non-strict to strict mode, we need to
    2773             :         // validate that all parameter names are valid strict mode names.
    2774             :         if (!inheritedStrict && pc->sc()->strict()) {
    2775           0 :             MOZ_ASSERT(pc->sc()->hasExplicitUseStrict(),
    2776          36 :                        "strict mode should only change when a 'use strict' directive is present");
    2777             :             if (!hasValidSimpleStrictParameterNames()) {
    2778          18 :                 // Request that this function be reparsed as strict to report
    2779             :                 // the invalid parameter name at the correct source location.
    2780             :                 pc->newDirectives->setStrict();
    2781           0 :                 return null();
    2782           0 :             }
    2783             :         }
    2784             :     } else {
    2785             :         MOZ_ASSERT(type == ExpressionBody);
    2786        1040 : 
    2787             :         // Async functions are implemented as generators, and generators are
    2788             :         // assumed to be statement lists, to prepend initial `yield`.
    2789             :         Node stmtList = null();
    2790           0 :         if (pc->isAsync()) {
    2791        2080 :             stmtList = handler.newStatementList(pos());
    2792           9 :             if (!stmtList)
    2793           0 :                 return null();
    2794             :         }
    2795             : 
    2796             :         Node kid = assignExpr(inHandling, yieldHandling, TripledotProhibited);
    2797        1040 :         if (!kid)
    2798           0 :             return null();
    2799             : 
    2800             :         pn = handler.newExpressionBody(kid);
    2801        2080 :         if (!pn)
    2802           0 :             return null();
    2803             : 
    2804             :         if (pc->isAsync()) {
    2805           0 :             handler.addStatementToList(stmtList, pn);
    2806           3 :             pn = stmtList;
    2807           3 :         }
    2808             :     }
    2809             : 
    2810             :     MOZ_ASSERT_IF(!pc->isGenerator() && !pc->isAsync(), pc->lastYieldOffset == startYieldOffset);
    2811       39131 :     MOZ_ASSERT_IF(pc->isGenerator(), kind != FunctionSyntaxKind::Arrow);
    2812       26114 :     MOZ_ASSERT_IF(pc->isGenerator(), type == StatementListBody);
    2813           0 : 
    2814             :     if (pc->needsDotGeneratorName()) {
    2815       13057 :         MOZ_ASSERT_IF(!pc->isAsync(), type == StatementListBody);
    2816        1458 :         if (!declareDotGeneratorName())
    2817           0 :             return null();
    2818             :         Node generator = newDotGeneratorName();
    2819           0 :         if (!generator)
    2820         729 :             return null();
    2821             :         if (!handler.prependInitialYield(pn, generator))
    2822         729 :             return null();
    2823             :     }
    2824             : 
    2825             :     // Declare the 'arguments' and 'this' bindings if necessary before
    2826             :     // finishing up the scope so these special bindings get marked as closed
    2827             :     // over if necessary. Arrow functions don't have these bindings.
    2828             :     if (kind != FunctionSyntaxKind::Arrow) {
    2829           0 :         if (!declareFunctionArgumentsObject())
    2830       10647 :             return null();
    2831             :         if (!declareFunctionThis())
    2832           0 :             return null();
    2833             :     }
    2834             : 
    2835             :     return finishLexicalScope(pc->varScope(), pn);
    2836       13057 : }
    2837             : 
    2838             : JSFunction*
    2839             : AllocNewFunction(JSContext* cx, HandleAtom atom, FunctionSyntaxKind kind, GeneratorKind generatorKind,
    2840       12242 :                  FunctionAsyncKind asyncKind, HandleObject proto,
    2841             :                  bool isSelfHosting /* = false */, bool inFunctionBox /* = false */)
    2842             : {
    2843             :     MOZ_ASSERT_IF(kind == FunctionSyntaxKind::Statement, atom != nullptr);
    2844           0 : 
    2845             :     RootedFunction fun(cx);
    2846       24484 : 
    2847             :     gc::AllocKind allocKind = gc::AllocKind::FUNCTION;
    2848           0 :     JSFunction::Flags flags;
    2849             : #ifdef DEBUG
    2850             :     bool isGlobalSelfHostedBuiltin = false;
    2851       12242 : #endif
    2852             :     switch (kind) {
    2853       12242 :       case FunctionSyntaxKind::Expression:
    2854             :         flags = (generatorKind == GeneratorKind::NotGenerator &&
    2855             :                  asyncKind == FunctionAsyncKind::SyncFunction
    2856             :                  ? JSFunction::INTERPRETED_LAMBDA
    2857        2165 :                  : JSFunction::INTERPRETED_LAMBDA_GENERATOR_OR_ASYNC);
    2858             :         break;
    2859             :       case FunctionSyntaxKind::Arrow:
    2860             :         flags = JSFunction::INTERPRETED_LAMBDA_ARROW;
    2861             :         allocKind = gc::AllocKind::FUNCTION_EXTENDED;
    2862             :         break;
    2863             :       case FunctionSyntaxKind::Method:
    2864             :         flags = (generatorKind == GeneratorKind::NotGenerator &&
    2865             :                  asyncKind == FunctionAsyncKind::SyncFunction
    2866             :                  ? JSFunction::INTERPRETED_METHOD
    2867             :                  : JSFunction::INTERPRETED_METHOD_GENERATOR_OR_ASYNC);
    2868             :         allocKind = gc::AllocKind::FUNCTION_EXTENDED;
    2869             :         break;
    2870             :       case FunctionSyntaxKind::ClassConstructor:
    2871             :       case FunctionSyntaxKind::DerivedClassConstructor:
    2872             :         flags = JSFunction::INTERPRETED_CLASS_CONSTRUCTOR;
    2873         164 :         allocKind = gc::AllocKind::FUNCTION_EXTENDED;
    2874         164 :         break;
    2875         164 :       case FunctionSyntaxKind::Getter:
    2876             :         flags = JSFunction::INTERPRETED_GETTER;
    2877         925 :         allocKind = gc::AllocKind::FUNCTION_EXTENDED;
    2878         925 :         break;
    2879         925 :       case FunctionSyntaxKind::Setter:
    2880             :         flags = JSFunction::INTERPRETED_SETTER;
    2881          98 :         allocKind = gc::AllocKind::FUNCTION_EXTENDED;
    2882          98 :         break;
    2883          98 :       default:
    2884             :         MOZ_ASSERT(kind == FunctionSyntaxKind::Statement);
    2885           0 : #ifdef DEBUG
    2886             :         if (isSelfHosting && !inFunctionBox) {
    2887           0 :             isGlobalSelfHostedBuiltin = true;
    2888         441 :             allocKind = gc::AllocKind::FUNCTION_EXTENDED;
    2889           0 :         }
    2890             : #endif
    2891             :         flags = (generatorKind == GeneratorKind::NotGenerator &&
    2892             :                  asyncKind == FunctionAsyncKind::SyncFunction
    2893             :                  ? JSFunction::INTERPRETED_NORMAL
    2894           0 :                  : JSFunction::INTERPRETED_GENERATOR_OR_ASYNC);
    2895             :     }
    2896             : 
    2897             :     // We store the async wrapper in a slot for later access.
    2898             :     if (asyncKind == FunctionAsyncKind::AsyncFunction)
    2899           0 :         allocKind = gc::AllocKind::FUNCTION_EXTENDED;
    2900           0 : 
    2901             :     fun = NewFunctionWithProto(cx, nullptr, 0, flags, nullptr, atom, proto,
    2902       24484 :                                allocKind, TenuredObject);
    2903       24484 :     if (!fun)
    2904       12242 :         return nullptr;
    2905             :     if (isSelfHosting) {
    2906           0 :         fun->setIsSelfHostedBuiltin();
    2907         480 : #ifdef DEBUG
    2908             :         if (isGlobalSelfHostedBuiltin)
    2909         480 :             fun->setExtendedSlot(HAS_SELFHOSTED_CANONICAL_NAME_SLOT, BooleanValue(false));
    2910         882 : #endif
    2911             :     }
    2912             :     return fun;
    2913       12242 : }
    2914             : 
    2915             : JSFunction*
    2916             : ParserBase::newFunction(HandleAtom atom, FunctionSyntaxKind kind,
    2917       12242 :                         GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
    2918             :                         HandleObject proto)
    2919             : {
    2920             :     return AllocNewFunction(context, atom, kind, generatorKind, asyncKind, proto,
    2921           0 :                             options().selfHostingMode, pc->isFunctionBox());
    2922           0 : }
    2923             : 
    2924             : template <class ParseHandler, typename CharT>
    2925             : bool
    2926             : GeneralParser<ParseHandler, CharT>::matchOrInsertSemicolon()
    2927       60754 : {
    2928             :     TokenKind tt = TokenKind::Eof;
    2929           0 :     if (!tokenStream.peekTokenSameLine(&tt, TokenStream::Operand))
    2930       60754 :         return false;
    2931             :     if (tt != TokenKind::Eof &&
    2932       60755 :         tt != TokenKind::Eol &&
    2933             :         tt != TokenKind::Semi &&
    2934           0 :         tt != TokenKind::Rc)
    2935             :     {
    2936             :         /*
    2937             :          * When current token is `await` and it's outside of async function,
    2938             :          * it's possibly intended to be an await expression.
    2939             :          *
    2940             :          *   await f();
    2941             :          *        ^
    2942             :          *        |
    2943             :          *        tried to insert semicolon here
    2944             :          *
    2945             :          * Detect this situation and throw an understandable error.  Otherwise
    2946             :          * we'd throw a confusing "unexpected token: (unexpected token)" error.
    2947             :          */
    2948             :         if (!pc->isAsync() && anyChars.currentToken().type == TokenKind::Await) {
    2949           0 :             error(JSMSG_AWAIT_OUTSIDE_ASYNC);
    2950           0 :             return false;
    2951           0 :         }
    2952             :         if (!yieldExpressionsSupported() && anyChars.currentToken().type == TokenKind::Yield) {
    2953           0 :             error(JSMSG_YIELD_OUTSIDE_GENERATOR);
    2954           0 :             return false;
    2955           0 :         }
    2956             : 
    2957             :         /* Advance the scanner for proper error location reporting. */
    2958             :         tokenStream.consumeKnownToken(tt, TokenStream::Operand);
    2959           0 :         error(JSMSG_UNEXPECTED_TOKEN_NO_EXPECT, TokenKindToDesc(tt));
    2960           0 :         return false;
    2961           0 :     }
    2962             :     bool matched;
    2963             :     return tokenStream.matchToken(&matched, TokenKind::Semi, TokenStream::Operand);
    2964       60755 : }
    2965             : 
    2966             : bool
    2967             : ParserBase::leaveInnerFunction(ParseContext* outerpc)
    2968       12242 : {
    2969             :     MOZ_ASSERT(pc != outerpc);
    2970       12242 : 
    2971             :     // If the current function allows super.property but cannot have a home
    2972             :     // object, i.e., it is an arrow function, we need to propagate the flag to
    2973             :     // the outer ParseContext.
    2974             :     if (pc->superScopeNeedsHomeObject()) {
    2975       12242 :         if (!pc->isArrowFunction())
    2976           0 :             MOZ_ASSERT(pc->functionBox()->needsHomeObject());
    2977         162 :         else
    2978             :             outerpc->setSuperScopeNeedsHomeObject();
    2979           2 :     }
    2980             : 
    2981             :     // Lazy functions inner to another lazy function need to be remembered by
    2982             :     // the inner function so that if the outer function is eventually parsed
    2983             :     // we do not need any further parsing or processing of the inner function.
    2984             :     //
    2985             :     // Append the inner function here unconditionally; the vector is only used
    2986             :     // if the Parser using outerpc is a syntax parsing. See
    2987             :     // GeneralParser<SyntaxParseHandler>::finishFunction.
    2988             :     if (!outerpc->innerFunctionsForLazy.append(pc->functionBox()->function()))
    2989           0 :         return false;
    2990             : 
    2991             :     PropagateTransitiveParseFlags(pc->functionBox(), outerpc->sc());
    2992       24484 : 
    2993             :     return true;
    2994             : }
    2995             : 
    2996             : JSAtom*
    2997             : ParserBase::prefixAccessorName(PropertyType propType, HandleAtom propAtom)
    2998        1023 : {
    2999             :     RootedAtom prefix(context);
    3000        3069 :     if (propType == PropertyType::Setter) {
    3001           0 :         prefix = context->names().setPrefix;
    3002         392 :     } else {
    3003             :         MOZ_ASSERT(propType == PropertyType::Getter);
    3004           0 :         prefix = context->names().getPrefix;
    3005        3700 :     }
    3006             : 
    3007             :     RootedString str(context, ConcatStrings<CanGC>(context, prefix, propAtom));
    3008        3069 :     if (!str)
    3009        1023 :         return nullptr;
    3010             : 
    3011             :     return AtomizeString(context, str);
    3012           0 : }
    3013             : 
    3014             : template <class ParseHandler, typename CharT>
    3015             : bool
    3016             : GeneralParser<ParseHandler, CharT>::functionArguments(YieldHandling yieldHandling,
    3017           0 :                                                       FunctionSyntaxKind kind,
    3018             :                                                       Node funcpn)
    3019             : {
    3020             :     FunctionBox* funbox = pc->functionBox();
    3021           0 : 
    3022             :     bool parenFreeArrow = false;
    3023       13057 :     // Modifier for the following tokens.
    3024             :     // TokenStream::None for the following cases:
    3025             :     //   async a => 1
    3026             :     //         ^
    3027             :     //
    3028             :     //   (a) => 1
    3029             :     //   ^
    3030             :     //
    3031             :     //   async (a) => 1
    3032             :     //         ^
    3033             :     //
    3034             :     //   function f(a) {}
    3035             :     //             ^
    3036             :     //
    3037             :     // TokenStream::Operand for the following case:
    3038             :     //   a => 1
    3039             :     //   ^
    3040             :     Modifier firstTokenModifier = TokenStream::None;
    3041       13057 : 
    3042             :     // Modifier for the the first token in each argument.
    3043             :     // can be changed to TokenStream::None for the following case:
    3044             :     //   async a => 1
    3045             :     //         ^
    3046             :     Modifier argModifier = TokenStream::Operand;
    3047       13057 :     if (kind == FunctionSyntaxKind::Arrow) {
    3048       13057 :         TokenKind tt;
    3049             :         // In async function, the first token after `async` is already gotten
    3050             :         // with TokenStream::None.
    3051             :         // In sync function, the first token is already gotten with
    3052             :         // TokenStream::Operand.
    3053             :         firstTokenModifier = funbox->isAsync() ? TokenStream::None : TokenStream::Operand;
    3054        2410 :         if (!tokenStream.peekToken(&tt, firstTokenModifier))
    3055        2410 :             return false;
    3056           0 :         if (TokenKindIsPossibleIdentifier(tt)) {
    3057        4820 :             parenFreeArrow = true;
    3058        1141 :             argModifier = firstTokenModifier;
    3059           0 :         }
    3060             :     }
    3061             : 
    3062             :     TokenPos firstTokenPos;
    3063       13057 :     if (!parenFreeArrow) {
    3064       13057 :         TokenKind tt;
    3065             :         if (!tokenStream.getToken(&tt, firstTokenModifier))
    3066           0 :             return false;
    3067           0 :         if (tt != TokenKind::Lp) {
    3068           1 :             error(kind == FunctionSyntaxKind::Arrow
    3069           0 :                   ? JSMSG_BAD_ARROW_ARGS
    3070             :                   : JSMSG_PAREN_BEFORE_FORMAL);
    3071             :             return false;
    3072           0 :         }
    3073             : 
    3074             :         firstTokenPos = pos();
    3075           0 : 
    3076             :         // Record the start of function source (for FunctionToString). If we
    3077             :         // are parenFreeArrow, we will set this below, after consuming the NAME.
    3078             :         funbox->setStart(anyChars);
    3079           0 :     } else {
    3080             :         // When delazifying, we may not have a current token and pos() is
    3081             :         // garbage. In that case, substitute the first token's position.
    3082             :         if (!tokenStream.peekTokenPos(&firstTokenPos, firstTokenModifier))
    3083        1141 :             return false;
    3084             :     }
    3085             : 
    3086             :     Node argsbody = handler.newList(ParseNodeKind::ParamsBody, firstTokenPos);
    3087           0 :     if (!argsbody)
    3088       13057 :         return false;
    3089             :     handler.setFunctionFormalParametersAndBody(funcpn, argsbody);
    3090       13057 : 
    3091             :     bool hasArguments = false;
    3092       13057 :     if (parenFreeArrow) {
    3093       13057 :         hasArguments = true;
    3094             :     } else {
    3095             :         bool matched;
    3096             :         if (!tokenStream.matchToken(&matched, TokenKind::Rp, TokenStream::Operand))
    3097       11916 :             return false;
    3098           0 :         if (!matched)
    3099           0 :             hasArguments = true;
    3100           0 :     }
    3101             :     if (hasArguments) {
    3102           0 :         bool hasRest = false;
    3103        8309 :         bool hasDefault = false;
    3104           0 :         bool duplicatedParam = false;
    3105           0 :         bool disallowDuplicateParams = kind == FunctionSyntaxKind::Arrow ||
    3106             :                                        kind == FunctionSyntaxKind::Method ||
    3107        8309 :                                        kind == FunctionSyntaxKind::ClassConstructor;
    3108        8309 :         AtomVector& positionalFormals = pc->positionalFormalParameterNames();
    3109           0 : 
    3110             :         if (kind == FunctionSyntaxKind::Getter) {
    3111           0 :             error(JSMSG_ACCESSOR_WRONG_ARGS, "getter", "no", "s");
    3112           0 :             return false;
    3113           0 :         }
    3114             : 
    3115             :         while (true) {
    3116           0 :             if (hasRest) {
    3117           0 :                 error(JSMSG_PARAMETER_AFTER_REST);
    3118           0 :                 return false;
    3119           0 :             }
    3120             : 
    3121             :             TokenKind tt;
    3122             :             if (!tokenStream.getToken(&tt, argModifier))
    3123           0 :                 return false;
    3124             :             argModifier = TokenStream::Operand;
    3125           0 :             MOZ_ASSERT_IF(parenFreeArrow, TokenKindIsPossibleIdentifier(tt));
    3126       14671 : 
    3127             :             if (tt == TokenKind::TripleDot) {
    3128           0 :                 if (kind == FunctionSyntaxKind::Setter) {
    3129           0 :                     error(JSMSG_ACCESSOR_WRONG_ARGS, "setter", "one", "");
    3130           0 :                     return false;
    3131           0 :                 }
    3132             : 
    3133             :                 disallowDuplicateParams = true;
    3134         152 :                 if (duplicatedParam) {
    3135           0 :                     // Has duplicated args before the rest parameter.
    3136             :                     error(JSMSG_BAD_DUP_ARGS);
    3137           0 :                     return false;
    3138           0 :                 }
    3139             : 
    3140             :                 hasRest = true;
    3141           0 :                 funbox->setHasRest();
    3142           0 : 
    3143             :                 if (!tokenStream.getToken(&tt))
    3144         152 :                     return false;
    3145             : 
    3146             :                 if (!TokenKindIsPossibleIdentifier(tt) &&
    3147           0 :                     tt != TokenKind::Lb &&
    3148         152 :                     tt != TokenKind::Lc)
    3149             :                 {
    3150             :                     error(JSMSG_NO_REST_NAME);
    3151           0 :                     return false;
    3152           0 :                 }
    3153             :             }
    3154             : 
    3155             :             switch (tt) {
    3156           0 :               case TokenKind::Lb:
    3157             :               case TokenKind::Lc: {
    3158             :                 disallowDuplicateParams = true;
    3159           0 :                 if (duplicatedParam) {
    3160           0 :                     // Has duplicated args before the destructuring parameter.
    3161             :                     error(JSMSG_BAD_DUP_ARGS);
    3162           0 :                     return false;
    3163           0 :                 }
    3164             : 
    3165             :                 funbox->hasDestructuringArgs = true;
    3166         108 : 
    3167             :                 Node destruct = destructuringDeclarationWithoutYieldOrAwait(
    3168             :                     DeclarationKind::FormalParameter,
    3169             :                     yieldHandling, tt);
    3170         108 :                 if (!destruct)
    3171           0 :                     return false;
    3172             : 
    3173             :                 if (!noteDestructuredPositionalFormalParameter(funcpn, destruct))
    3174           0 :                     return false;
    3175             : 
    3176             :                 break;
    3177             :               }
    3178             : 
    3179             :               default: {
    3180             :                 if (!TokenKindIsPossibleIdentifier(tt)) {
    3181       26844 :                     error(JSMSG_MISSING_FORMAL);
    3182           0 :                     return false;
    3183           0 :                 }
    3184             : 
    3185             :                 if (parenFreeArrow)
    3186           0 :                     funbox->setStart(anyChars);
    3187        1141 : 
    3188             :                 RootedPropertyName name(context, bindingIdentifier(yieldHandling));
    3189       13422 :                 if (!name)
    3190       13422 :                     return false;
    3191           0 : 
    3192             :                 if (!notePositionalFormalParameter(funcpn, name, pos().begin,
    3193           0 :                                                    disallowDuplicateParams, &duplicatedParam))
    3194             :                 {
    3195             :                     return false;
    3196             :                 }
    3197             :                 if (duplicatedParam)
    3198           0 :                     funbox->hasDuplicateParameters = true;
    3199           0 : 
    3200             :                 break;
    3201           0 :               }
    3202             :             }
    3203             : 
    3204             :             if (positionalFormals.length() >= ARGNO_LIMIT) {
    3205           0 :                 error(JSMSG_TOO_MANY_FUN_ARGS);
    3206           0 :                 return false;
    3207           0 :             }
    3208             : 
    3209             :             // The next step is to detect arguments with default expressions,
    3210             :             // e.g. |function parseInt(str, radix = 10) {}|.  But if we have a
    3211             :             // parentheses-free arrow function, |a => ...|, the '=' necessary
    3212             :             // for a default expression would really be an assignment operator:
    3213             :             // that is, |a = b => 42;| would parse as |a = (b => 42);|.  So we
    3214             :             // should stop parsing arguments here.
    3215             :             if (parenFreeArrow)
    3216       13530 :                 break;
    3217             : 
    3218             :             bool matched;
    3219             :             if (!tokenStream.matchToken(&matched, TokenKind::Assign, TokenStream::Operand))
    3220       12389 :                 return false;
    3221             :             if (matched) {
    3222       12389 :                 // A default argument without parentheses would look like:
    3223             :                 // a = expr => body, but both operators are right-associative, so
    3224             :                 // that would have been parsed as a = (expr => body) instead.
    3225             :                 // Therefore it's impossible to get here with parenFreeArrow.
    3226             :                 MOZ_ASSERT(!parenFreeArrow);
    3227         545 : 
    3228             :                 if (hasRest) {
    3229         545 :                     error(JSMSG_REST_WITH_DEFAULT);
    3230           0 :                     return false;
    3231           0 :                 }
    3232             :                 disallowDuplicateParams = true;
    3233         545 :                 if (duplicatedParam) {
    3234           0 :                     error(JSMSG_BAD_DUP_ARGS);
    3235           0 :                     return false;
    3236           0 :                 }
    3237             : 
    3238             :                 if (!hasDefault) {
    3239           0 :                     hasDefault = true;
    3240         471 : 
    3241             :                     // The Function.length property is the number of formals
    3242             :                     // before the first default argument.
    3243             :                     funbox->length = positionalFormals.length() - 1;
    3244         471 :                 }
    3245             :                 funbox->hasParameterExprs = true;
    3246           0 : 
    3247             :                 Node def_expr = assignExprWithoutYieldOrAwait(yieldHandling);
    3248           0 :                 if (!def_expr)
    3249         545 :                     return false;
    3250             :                 if (!handler.setLastFunctionFormalParameterDefault(funcpn, def_expr))
    3251           0 :                     return false;
    3252             :             }
    3253             : 
    3254             :             // Setter syntax uniquely requires exactly one argument.
    3255             :             if (kind == FunctionSyntaxKind::Setter)
    3256           0 :                 break;
    3257             : 
    3258             :             if (!tokenStream.matchToken(&matched, TokenKind::Comma, TokenStream::Operand))
    3259       12291 :                 return false;
    3260             :             if (!matched)
    3261           0 :                 break;
    3262             : 
    3263             :             if (!hasRest) {
    3264        5221 :                 if (!tokenStream.peekToken(&tt, TokenStream::Operand))
    3265        5221 :                     return null();
    3266             :                 if (tt == TokenKind::Rp)
    3267        5221 :                     break;
    3268             :             }
    3269             :         }
    3270             : 
    3271             :         if (!parenFreeArrow) {
    3272        8309 :             TokenKind tt;
    3273             :             if (!tokenStream.getToken(&tt, TokenStream::Operand))
    3274        7168 :                 return false;
    3275           0 :             if (tt != TokenKind::Rp) {
    3276           0 :                 if (kind == FunctionSyntaxKind::Setter) {
    3277           0 :                     error(JSMSG_ACCESSOR_WRONG_ARGS, "setter", "one", "");
    3278           0 :                     return false;
    3279           0 :                 }
    3280             : 
    3281             :                 error(JSMSG_PAREN_AFTER_FORMAL);
    3282           0 :                 return false;
    3283           0 :             }
    3284             :         }
    3285             : 
    3286             :         if (!hasDefault)
    3287           0 :             funbox->length = positionalFormals.length() - hasRest;
    3288           0 : 
    3289             :         if (funbox->hasParameterExprs && funbox->hasDirectEval())
    3290           0 :             funbox->hasDirectEvalInParameterExpr = true;
    3291           0 : 
    3292             :         funbox->function()->setArgCount(positionalFormals.length());
    3293       24927 :     } else if (kind == FunctionSyntaxKind::Setter) {
    3294           0 :         error(JSMSG_ACCESSOR_WRONG_ARGS, "setter", "one", "");
    3295           0 :         return false;
    3296           0 :     }
    3297             : 
    3298             :     return true;
    3299             : }
    3300             : 
    3301             : template <typename CharT>
    3302             : bool
    3303             : Parser<FullParseHandler, CharT>::skipLazyInnerFunction(ParseNode* funcNode, uint32_t toStringStart,
    3304           0 :                                                        FunctionSyntaxKind kind, bool tryAnnexB)
    3305             : {
    3306             :     // When a lazily-parsed function is called, we only fully parse (and emit)
    3307             :     // that function, not any of its nested children. The initial syntax-only
    3308             :     // parse recorded the free variables of nested functions and their extents,
    3309             :     // so we can skip over them after accounting for their free variables.
    3310             : 
    3311             :     RootedFunction fun(context, handler.nextLazyInnerFunction());
    3312           0 :     FunctionBox* funbox =
    3313             :         newFunctionBox(funcNode, fun, toStringStart, Directives(/* strict = */ false),
    3314           0 :                        fun->generatorKind(), fun->asyncKind());
    3315           0 :     if (!funbox)
    3316           0 :         return false;
    3317             : 
    3318             :     LazyScript* lazy = fun->lazyScript();
    3319           0 :     if (lazy->needsHomeObject())
    3320           0 :         funbox->setNeedsHomeObject();
    3321           0 : 
    3322             :     PropagateTransitiveParseFlags(lazy, pc->sc());
    3323           0 : 
    3324             :     if (!tokenStream.advance(fun->lazyScript()->sourceEnd()))
    3325           0 :         return false;
    3326             : 
    3327             :     // Append possible Annex B function box only upon successfully parsing.
    3328             :     if (tryAnnexB && !pc->innermostScope()->addPossibleAnnexBFunctionBox(pc, funbox))
    3329           0 :         return false;
    3330             : 
    3331             :     return true;
    3332           0 : }
    3333             : 
    3334             : template <typename CharT>
    3335             : bool
    3336             : Parser<SyntaxParseHandler, CharT>::skipLazyInnerFunction(Node funcNode, uint32_t toStringStart,
    3337           0 :                                                          FunctionSyntaxKind kind,
    3338             :                                                          bool tryAnnexB)
    3339             : {
    3340             :     MOZ_CRASH("Cannot skip lazy inner functions when syntax parsing");
    3341           0 : }
    3342             : 
    3343             : template <class ParseHandler, typename CharT>
    3344             : bool
    3345             : GeneralParser<ParseHandler, CharT>::skipLazyInnerFunction(Node funcNode, uint32_t toStringStart,
    3346           0 :                                                           FunctionSyntaxKind kind,
    3347             :                                                           bool tryAnnexB)
    3348             : {
    3349             :     return asFinalParser()->skipLazyInnerFunction(funcNode, toStringStart, kind, tryAnnexB);
    3350           0 : }
    3351             : 
    3352             : template <class ParseHandler, typename CharT>
    3353             : bool
    3354             : GeneralParser<ParseHandler, CharT>::addExprAndGetNextTemplStrToken(YieldHandling yieldHandling,
    3355        1090 :                                                                    Node nodeList,
    3356             :                                                                    TokenKind* ttp)
    3357             : {
    3358             :     Node pn = expr(InAllowed, yieldHandling, TripledotProhibited);
    3359        1090 :     if (!pn)
    3360        1090 :         return false;
    3361             :     handler.addList(nodeList, pn);
    3362           1 : 
    3363             :     TokenKind tt;
    3364             :     if (!tokenStream.getToken(&tt, TokenStream::Operand))
    3365        1090 :         return false;
    3366             :     if (tt != TokenKind::Rc) {
    3367           0 :         error(JSMSG_TEMPLSTR_UNTERM_EXPR);
    3368           0 :         return false;
    3369           0 :     }
    3370             : 
    3371             :     return tokenStream.getToken(ttp, TokenStream::TemplateTail);
    3372           0 : }
    3373             : 
    3374             : template <class ParseHandler, typename CharT>
    3375             : bool
    3376             : GeneralParser<ParseHandler, CharT>::taggedTemplate(YieldHandling yieldHandling, Node nodeList,
    3377           0 :                                                    TokenKind tt)
    3378             : {
    3379             :     Node callSiteObjNode = handler.newCallSiteObject(pos().begin);
    3380           0 :     if (!callSiteObjNode)
    3381           0 :         return false;
    3382             :     handler.addList(nodeList, callSiteObjNode);
    3383           7 : 
    3384             :     while (true) {
    3385             :         if (!appendToCallSiteObj(callSiteObjNode))
    3386          13 :             return false;
    3387             :         if (tt != TokenKind::TemplateHead)
    3388          13 :             break;
    3389             : 
    3390             :         if (!addExprAndGetNextTemplStrToken(yieldHandling, nodeList, &tt))
    3391           6 :             return false;
    3392             :     }
    3393             :     handler.setEndPosition(nodeList, callSiteObjNode);
    3394          14 :     return true;
    3395           0 : }
    3396             : 
    3397             : template <class ParseHandler, typename CharT>
    3398             : typename ParseHandler::Node
    3399             : GeneralParser<ParseHandler, CharT>::templateLiteral(YieldHandling yieldHandling)
    3400           0 : {
    3401             :     Node pn = noSubstitutionUntaggedTemplate();
    3402         757 :     if (!pn)
    3403           0 :         return null();
    3404             : 
    3405             :     Node nodeList = handler.newList(ParseNodeKind::TemplateStringList, pn);
    3406           0 :     if (!nodeList)
    3407           0 :         return null();
    3408             : 
    3409             :     TokenKind tt;
    3410             :     do {
    3411             :         if (!addExprAndGetNextTemplStrToken(yieldHandling, nodeList, &tt))
    3412           0 :             return null();
    3413             : 
    3414             :         pn = noSubstitutionUntaggedTemplate();
    3415           0 :         if (!pn)
    3416        1084 :             return null();
    3417             : 
    3418             :         handler.addList(nodeList, pn);
    3419           0 :     } while (tt == TokenKind::TemplateHead);
    3420        1084 :     return nodeList;
    3421             : }
    3422             : 
    3423             : template <class ParseHandler, typename CharT>
    3424             : typename ParseHandler::Node
    3425             : GeneralParser<ParseHandler, CharT>::functionDefinition(Node funcNode, uint32_t toStringStart,
    3426       12242 :                                                        InHandling inHandling, YieldHandling yieldHandling,
    3427             :                                                        HandleAtom funName, FunctionSyntaxKind kind,
    3428             :                                                        GeneratorKind generatorKind,
    3429             :                                                        FunctionAsyncKind asyncKind,
    3430             :                                                        bool tryAnnexB /* = false */)
    3431             : {
    3432             :     MOZ_ASSERT_IF(kind == FunctionSyntaxKind::Statement, funName);
    3433       13877 : 
    3434             :     // When fully parsing a LazyScript, we do not fully reparse its inner
    3435             :     // functions, which are also lazy. Instead, their free variables and
    3436             :     // source extents are recorded and may be skipped.
    3437             :     if (handler.canSkipLazyInnerFunctions()) {
    3438           0 :         if (!skipLazyInnerFunction(funcNode, toStringStart, kind, tryAnnexB))
    3439           0 :             return null();
    3440             : 
    3441             :         return funcNode;
    3442           0 :     }
    3443             : 
    3444             :     RootedObject proto(context);
    3445           0 :     if (generatorKind == GeneratorKind::Generator ||
    3446       12242 :         asyncKind == FunctionAsyncKind::AsyncFunction)
    3447             :     {
    3448             :         proto = GlobalObject::getOrCreateGeneratorFunctionPrototype(context, context->global());
    3449        2187 :         if (!proto)
    3450           0 :             return null();
    3451             :     }
    3452             :     RootedFunction fun(context, newFunction(funName, kind, generatorKind, asyncKind, proto));
    3453       24484 :     if (!fun)
    3454           1 :         return null();
    3455             : 
    3456             :     // Speculatively parse using the directives of the parent parsing context.
    3457             :     // If a directive is encountered (e.g., "use strict") that changes how the
    3458             :     // function should have been parsed, we backup and reparse with the new set
    3459             :     // of directives.
    3460             :     Directives directives(pc);
    3461           0 :     Directives newDirectives = directives;
    3462           0 : 
    3463             :     Position start(keepAtoms, tokenStream);
    3464       12242 : 
    3465             :     // Parse the inner function. The following is a loop as we may attempt to
    3466             :     // reparse a function due to failed syntax parsing and encountering new
    3467             :     // "use foo" directives.
    3468             :     while (true) {
    3469             :         if (trySyntaxParseInnerFunction(&funcNode, fun, toStringStart, inHandling, yieldHandling,
    3470       36726 :                                         kind, generatorKind, asyncKind, tryAnnexB, directives,
    3471             :                                         &newDirectives))
    3472             :         {
    3473             :             break;
    3474             :         }
    3475             : 
    3476             :         // Return on error.
    3477             :         if (anyChars.hadError() || directives == newDirectives)
    3478           0 :             return null();
    3479             : 
    3480             :         // Assignment must be monotonic to prevent infinitely attempting to
    3481             :         // reparse.
    3482             :         MOZ_ASSERT_IF(directives.strict(), newDirectives.strict());
    3483           0 :         MOZ_ASSERT_IF(directives.asmJS(), newDirectives.asmJS());
    3484           0 :         directives = newDirectives;
    3485           0 : 
    3486             :         tokenStream.seek(start);
    3487           0 : 
    3488             :         // functionFormalParametersAndBody may have already set pn->pn_body before failing.
    3489             :         handler.setFunctionFormalParametersAndBody(funcNode, null());
    3490           0 :     }
    3491             : 
    3492             :     return funcNode;
    3493       12242 : }
    3494             : 
    3495             : template <typename CharT>
    3496             : bool
    3497             : Parser<FullParseHandler, CharT>::trySyntaxParseInnerFunction(ParseNode** funcNode,
    3498       12242 :                                                              HandleFunction fun,
    3499             :                                                              uint32_t toStringStart,
    3500             :                                                              InHandling inHandling,
    3501             :                                                              YieldHandling yieldHandling,
    3502             :                                                              FunctionSyntaxKind kind,
    3503             :                                                              GeneratorKind generatorKind,
    3504             :                                                              FunctionAsyncKind asyncKind,
    3505             :                                                              bool tryAnnexB,
    3506             :                                                              Directives inheritedDirectives,
    3507             :                                                              Directives* newDirectives)
    3508             : {
    3509             :     // Try a syntax parse for this inner function.
    3510             :     do {
    3511             :         // If we're assuming this function is an IIFE, always perform a full
    3512             :         // parse to avoid the overhead of a lazy syntax-only parse. Although
    3513             :         // the prediction may be incorrect, IIFEs are common enough that it
    3514             :         // pays off for lots of code.
    3515             :         if ((*funcNode)->isLikelyIIFE() &&
    3516       36726 :             generatorKind == GeneratorKind::NotGenerator &&
    3517       12242 :             asyncKind == FunctionAsyncKind::SyncFunction)
    3518             :         {
    3519             :             break;
    3520             :         }
    3521             : 
    3522             :         SyntaxParser* syntaxParser = getSyntaxParser();
    3523       24338 :         if (!syntaxParser)
    3524       12169 :             break;
    3525             : 
    3526             :         UsedNameTracker::RewindToken token = usedNames.getRewindToken();
    3527           0 : 
    3528             :         // Move the syntax parser to the current position in the stream.
    3529             :         Position currentPosition(keepAtoms, tokenStream);
    3530           0 :         if (!syntaxParser->tokenStream.seek(currentPosition, anyChars))
    3531           0 :             return false;
    3532           0 : 
    3533             :         // Make a FunctionBox before we enter the syntax parser, because |pn|
    3534             :         // still expects a FunctionBox to be attached to it during BCE, and
    3535             :         // the syntax parser cannot attach one to it.
    3536             :         FunctionBox* funbox = newFunctionBox(*funcNode, fun, toStringStart, inheritedDirectives,
    3537           0 :                                              generatorKind, asyncKind);
    3538           0 :         if (!funbox)
    3539           0 :             return false;
    3540             :         funbox->initWithEnclosingParseContext(pc, kind);
    3541           0 : 
    3542             :         SyntaxParseHandler::Node syntaxNode =
    3543             :             syntaxParser->innerFunctionForFunctionBox(SyntaxParseHandler::NodeGeneric, pc, funbox,
    3544             :                                                       inHandling, yieldHandling, kind,
    3545             :                                                       newDirectives);
    3546           0 :         if (!syntaxNode) {
    3547           0 :             if (syntaxParser->hadAbortedSyntaxParse()) {
    3548           0 :                 // Try again with a full parse. UsedNameTracker needs to be
    3549             :                 // rewound to just before we tried the syntax parse for
    3550             :                 // correctness.
    3551             :                 syntaxParser->clearAbortedSyntaxParse();
    3552           0 :                 usedNames.rewind(token);
    3553           0 :                 MOZ_ASSERT_IF(!syntaxParser->context->helperThread(),
    3554           0 :                               !syntaxParser->context->isExceptionPending());
    3555             :                 break;
    3556             :             }
    3557             :             return false;
    3558             :         }
    3559             : 
    3560             :         // Advance this parser over tokens processed by the syntax parser.
    3561             :         Position currentSyntaxPosition(keepAtoms, syntaxParser->tokenStream);
    3562           0 :         if (!tokenStream.seek(currentSyntaxPosition, syntaxParser->anyChars))
    3563           0 :             return false;
    3564             : 
    3565             :         // Update the end position of the parse node.
    3566             :         (*funcNode)->pn_pos.end = anyChars.currentToken().pos.end;
    3567           0 : 
    3568             :         // Append possible Annex B function box only upon successfully parsing.
    3569             :         if (tryAnnexB) {
    3570           0 :             if (!pc->innermostScope()->addPossibleAnnexBFunctionBox(pc, funbox))
    3571           0 :                 return false;
    3572             :         }
    3573             : 
    3574             :         return true;
    3575             :     } while (false);
    3576             : 
    3577             :     // We failed to do a syntax parse above, so do the full parse.
    3578             :     Node innerFunc =
    3579             :         innerFunction(*funcNode, pc, fun, toStringStart, inHandling, yieldHandling, kind,
    3580       12242 :                       generatorKind, asyncKind, tryAnnexB, inheritedDirectives, newDirectives);
    3581       12242 :     if (!innerFunc)
    3582           1 :         return false;
    3583             : 
    3584             :     *funcNode = innerFunc;
    3585       12242 :     return true;
    3586       12242 : }
    3587             : 
    3588             : template <typename CharT>
    3589             : bool
    3590             : Parser<SyntaxParseHandler, CharT>::trySyntaxParseInnerFunction(Node* funcNode, HandleFunction fun,
    3591           0 :                                                                uint32_t toStringStart,
    3592             :                                                                InHandling inHandling,
    3593             :                                                                YieldHandling yieldHandling,
    3594             :                                                                FunctionSyntaxKind kind,
    3595             :                                                                GeneratorKind generatorKind,
    3596             :                                                                FunctionAsyncKind asyncKind,
    3597             :                                                                bool tryAnnexB,
    3598             :                                                                Directives inheritedDirectives,
    3599             :                                                                Directives* newDirectives)
    3600             : {
    3601             :     // This is already a syntax parser, so just parse the inner function.
    3602             :     Node innerFunc =
    3603             :         innerFunction(*funcNode, pc, fun, toStringStart, inHandling, yieldHandling, kind,
    3604           0 :                       generatorKind, asyncKind, tryAnnexB, inheritedDirectives, newDirectives);
    3605           0 : 
    3606             :     if (!innerFunc)
    3607           0 :         return false;
    3608             : 
    3609             :     *funcNode = innerFunc;
    3610           0 :     return true;
    3611           0 : }
    3612             : 
    3613             : template <class ParseHandler, typename CharT>
    3614             : inline bool
    3615             : GeneralParser<ParseHandler, CharT>::trySyntaxParseInnerFunction(Node* funcNode, HandleFunction fun,
    3616           0 :                                                                 uint32_t toStringStart,
    3617             :                                                                 InHandling inHandling,
    3618             :                                                                 YieldHandling yieldHandling,
    3619             :                                                                 FunctionSyntaxKind kind,
    3620             :                                                                 GeneratorKind generatorKind,
    3621             :                                                                 FunctionAsyncKind asyncKind,
    3622             :                                                                 bool tryAnnexB,
    3623             :                                                                 Directives inheritedDirectives,
    3624             :                                                                 Directives* newDirectives)
    3625             : {
    3626             :     return asFinalParser()->trySyntaxParseInnerFunction(funcNode, fun, toStringStart, inHandling,
    3627             :                                                         yieldHandling, kind, generatorKind,
    3628             :                                                         asyncKind, tryAnnexB, inheritedDirectives,
    3629             :                                                         newDirectives);
    3630       12242 : }
    3631             : 
    3632             : template <class ParseHandler, typename CharT>
    3633             : typename ParseHandler::Node
    3634             : GeneralParser<ParseHandler, CharT>::innerFunctionForFunctionBox(Node funcNode,
    3635       12242 :                                                                 ParseContext* outerpc,
    3636             :                                                                 FunctionBox* funbox,
    3637             :                                                                 InHandling inHandling,
    3638             :                                                                 YieldHandling yieldHandling,
    3639             :                                                                 FunctionSyntaxKind kind,
    3640             :                                                                 Directives* newDirectives)
    3641             : {
    3642             :     // Note that it is possible for outerpc != this->pc, as we may be
    3643             :     // attempting to syntax parse an inner function from an outer full
    3644             :     // parser. In that case, outerpc is a SourceParseContext from the full parser
    3645             :     // instead of the current top of the stack of the syntax parser.
    3646             : 
    3647             :     // Push a new ParseContext.
    3648             :     SourceParseContext funpc(this, funbox, newDirectives);
    3649       36726 :     if (!funpc.init())
    3650       12242 :         return null();
    3651             : 
    3652             :     if (!functionFormalParametersAndBody(inHandling, yieldHandling, &funcNode, kind))
    3653       24484 :         return null();
    3654             : 
    3655             :     if (!leaveInnerFunction(outerpc))
    3656       12242 :         return null();
    3657             : 
    3658             :     return funcNode;
    3659       12242 : }
    3660             : 
    3661             : template <class ParseHandler, typename CharT>
    3662             : typename ParseHandler::Node
    3663             : GeneralParser<ParseHandler, CharT>::innerFunction(Node funcNode, ParseContext* outerpc,
    3664       12242 :                                                   HandleFunction fun, uint32_t toStringStart,
    3665             :                                                   InHandling inHandling,
    3666             :                                                   YieldHandling yieldHandling,
    3667             :                                                   FunctionSyntaxKind kind,
    3668             :                                                   GeneratorKind generatorKind,
    3669             :                                                   FunctionAsyncKind asyncKind, bool tryAnnexB,
    3670             :                                                   Directives inheritedDirectives,
    3671             :                                                   Directives* newDirectives)
    3672             : {
    3673             :     // Note that it is possible for outerpc != this->pc, as we may be
    3674             :     // attempting to syntax parse an inner function from an outer full
    3675             :     // parser. In that case, outerpc is a SourceParseContext from the full parser
    3676             :     // instead of the current top of the stack of the syntax parser.
    3677             : 
    3678             :     FunctionBox* funbox = newFunctionBox(funcNode, fun, toStringStart, inheritedDirectives,
    3679       12242 :                                          generatorKind, asyncKind);
    3680       12242 :     if (!funbox)
    3681       12242 :         return null();
    3682             :     funbox->initWithEnclosingParseContext(outerpc, kind);
    3683       12242 : 
    3684             :     Node innerFunc =
    3685             :         innerFunctionForFunctionBox(funcNode, outerpc, funbox, inHandling, yieldHandling, kind,
    3686             :                                      newDirectives);
    3687       12242 :     if (!innerFunc)
    3688       12242 :         return null();
    3689             : 
    3690             :     // Append possible Annex B function box only upon successfully parsing.
    3691             :     if (tryAnnexB) {
    3692           0 :         if (!pc->innermostScope()->addPossibleAnnexBFunctionBox(pc, funbox))
    3693           0 :             return null();
    3694             :     }
    3695             : 
    3696             :     return innerFunc;
    3697             : }
    3698             : 
    3699             : template <class ParseHandler, typename CharT>
    3700             : bool
    3701             : GeneralParser<ParseHandler, CharT>::appendToCallSiteObj(Node callSiteObj)
    3702          13 : {
    3703             :     Node cookedNode = noSubstitutionTaggedTemplate();
    3704           0 :     if (!cookedNode)
    3705           0 :         return false;
    3706             : 
    3707             :     JSAtom* atom = tokenStream.getRawTemplateStringAtom();
    3708          13 :     if (!atom)
    3709          13 :         return false;
    3710             :     Node rawNode = handler.newTemplateStringLiteral(atom, pos());
    3711          39 :     if (!rawNode)
    3712          13 :         return false;
    3713             : 
    3714             :     handler.addToCallSiteObject(callSiteObj, rawNode, cookedNode);
    3715          13 :     return true;
    3716           0 : }
    3717             : 
    3718             : template <typename CharT>
    3719             : ParseNode*
    3720             : Parser<FullParseHandler, CharT>::standaloneLazyFunction(HandleFunction fun, uint32_t toStringStart,
    3721           0 :                                                         bool strict, GeneratorKind generatorKind,
    3722             :                                                         FunctionAsyncKind asyncKind)
    3723             : {
    3724             :     MOZ_ASSERT(checkOptionsCalled);
    3725           0 : 
    3726             :     Node pn = handler.newFunctionStatement(pos());
    3727           0 :     if (!pn)
    3728           0 :         return null();
    3729             : 
    3730             :     Directives directives(strict);
    3731           0 :     FunctionBox* funbox = newFunctionBox(pn, fun, toStringStart, directives, generatorKind,
    3732           0 :                                          asyncKind);
    3733           0 :     if (!funbox)
    3734           0 :         return null();
    3735             :     funbox->initFromLazyFunction();
    3736           0 : 
    3737             :     Directives newDirectives = directives;
    3738           0 :     SourceParseContext funpc(this, funbox, &newDirectives);
    3739           0 :     if (!funpc.init())
    3740           0 :         return null();
    3741             : 
    3742             :     // Our tokenStream has no current token, so pn's position is garbage.
    3743             :     // Substitute the position of the first token in our source.  If the
    3744             :     // function is a not-async arrow, use TokenStream::Operand to keep
    3745             :     // verifyConsistentModifier from complaining (we will use
    3746             :     // TokenStream::Operand in functionArguments).
    3747             :     Modifier modifier = (fun->isArrow() && asyncKind == FunctionAsyncKind::SyncFunction)
    3748           0 :                         ? TokenStream::Operand
    3749           0 :                         : TokenStream::None;
    3750           0 :     if (!tokenStream.peekTokenPos(&pn->pn_pos, modifier))
    3751           0 :         return null();
    3752             : 
    3753             :     YieldHandling yieldHandling = GetYieldHandling(generatorKind);
    3754           0 :     FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::Statement;
    3755           0 :     if (fun->isClassConstructor())
    3756           0 :         syntaxKind = FunctionSyntaxKind::ClassConstructor;
    3757             :     else if (fun->isMethod())
    3758           0 :         syntaxKind = FunctionSyntaxKind::Method;
    3759             :     else if (fun->isGetter())
    3760           0 :         syntaxKind = FunctionSyntaxKind::Getter;
    3761             :     else if (fun->isSetter())
    3762           0 :         syntaxKind = FunctionSyntaxKind::Setter;
    3763             :     else if (fun->isArrow())
    3764           0 :         syntaxKind = FunctionSyntaxKind::Arrow;
    3765           0 : 
    3766             :     if (!functionFormalParametersAndBody(InAllowed, yieldHandling, &pn, syntaxKind)) {
    3767           0 :         MOZ_ASSERT(directives == newDirectives);
    3768           0 :         return null();
    3769             :     }
    3770             : 
    3771             :     if (!FoldConstants(context, &pn, this))
    3772           0 :         return null();
    3773             : 
    3774             :     return pn;
    3775           0 : }
    3776             : 
    3777             : template <class ParseHandler, typename CharT>
    3778             : bool
    3779             : GeneralParser<ParseHandler, CharT>::functionFormalParametersAndBody(InHandling inHandling,
    3780           1 :                                                                     YieldHandling yieldHandling,
    3781             :                                                                     Node* pn,
    3782             :                                                                     FunctionSyntaxKind kind,
    3783             :                                                                     const Maybe<uint32_t>& parameterListEnd /* = Nothing() */,
    3784             :                                                                     bool isStandaloneFunction /* = false */)
    3785             : {
    3786             :     // Given a properly initialized parse context, try to parse an actual
    3787             :     // function without concern for conversion to strict mode, use of lazy
    3788             :     // parsing and such.
    3789             : 
    3790             :     FunctionBox* funbox = pc->functionBox();
    3791       26114 :     RootedFunction fun(context, funbox->function());
    3792           0 : 
    3793             :     // See below for an explanation why arrow function parameters and arrow
    3794             :     // function bodies are parsed with different yield/await settings.
    3795             :     {
    3796             :         AwaitHandling awaitHandling =
    3797             :             (funbox->isAsync() || (kind == FunctionSyntaxKind::Arrow && awaitIsKeyword()))
    3798       27718 :             ? AwaitIsKeyword
    3799       13057 :             : AwaitIsName;
    3800       13057 :         AutoAwaitIsKeyword<ParseHandler, CharT> awaitIsKeyword(this, awaitHandling);
    3801       39171 :         if (!functionArguments(yieldHandling, kind, *pn))
    3802       13057 :             return false;
    3803           0 :     }
    3804             : 
    3805             :     Maybe<ParseContext::VarScope> varScope;
    3806       13057 :     if (funbox->hasParameterExprs) {
    3807       13057 :         varScope.emplace(this);
    3808         473 :         if (!varScope->init(pc))
    3809         473 :             return false;
    3810             :     } else {
    3811             :         pc->functionScope().useAsVarScope(pc);
    3812           0 :     }
    3813             : 
    3814             :     if (kind == FunctionSyntaxKind::Arrow) {
    3815           0 :         bool matched;
    3816             :         if (!tokenStream.matchToken(&matched, TokenKind::Arrow))
    3817        2410 :             return false;
    3818           0 :         if (!matched) {
    3819           0 :             error(JSMSG_BAD_ARROW_ARGS);
    3820           0 :             return false;
    3821           0 :         }
    3822             :     }
    3823             : 
    3824             :     // When parsing something for new Function() we have to make sure to
    3825             :     // only treat a certain part of the source as a parameter list.
    3826             :     if (parameterListEnd.isSome() && parameterListEnd.value() != pos().begin) {
    3827           0 :         error(JSMSG_UNEXPECTED_PARAMLIST_END);
    3828           0 :         return false;
    3829           0 :     }
    3830             : 
    3831             :     // Parse the function body.
    3832             :     FunctionBodyType bodyType = StatementListBody;
    3833           0 :     TokenKind tt;
    3834             :     if (!tokenStream.getToken(&tt, TokenStream::Operand))
    3835       13057 :         return false;
    3836             :     uint32_t openedPos = 0;
    3837       13057 :     if (tt != TokenKind::Lc) {
    3838       13057 :         if (kind != FunctionSyntaxKind::Arrow) {
    3839           0 :             error(JSMSG_CURLY_BEFORE_BODY);
    3840           0 :             return false;
    3841           0 :         }
    3842             : 
    3843             :         anyChars.ungetToken();
    3844        1040 :         bodyType = ExpressionBody;
    3845           0 :         funbox->setHasExprBody();
    3846        1040 :     } else {
    3847             :         openedPos = pos().begin;
    3848       24034 :     }
    3849             : 
    3850             :     // Arrow function parameters inherit yieldHandling from the enclosing
    3851             :     // context, but the arrow body doesn't. E.g. in |(a = yield) => yield|,
    3852             :     // |yield| in the parameters is either a name or keyword, depending on
    3853             :     // whether the arrow function is enclosed in a generator function or not.
    3854             :     // Whereas the |yield| in the function body is always parsed as a name.
    3855             :     // The same goes when parsing |await| in arrow functions.
    3856             :     YieldHandling bodyYieldHandling = GetYieldHandling(pc->generatorKind());
    3857           0 :     AwaitHandling bodyAwaitHandling = GetAwaitHandling(pc->asyncKind());
    3858           0 :     bool inheritedStrict = pc->sc()->strict();
    3859       26114 :     Node body;
    3860             :     {
    3861             :         AutoAwaitIsKeyword<ParseHandler, CharT> awaitIsKeyword(this, bodyAwaitHandling);
    3862       39171 :         body = functionBody(inHandling, bodyYieldHandling, kind, bodyType);
    3863       13057 :         if (!body)
    3864       13057 :             return false;
    3865           0 :     }
    3866             : 
    3867             :     // Revalidate the function name when we transitioned to strict mode.
    3868             :     if ((kind == FunctionSyntaxKind::Statement || kind == FunctionSyntaxKind::Expression) &&
    3869           0 :         fun->explicitName() &&
    3870           0 :         !inheritedStrict &&
    3871           0 :         pc->sc()->strict())
    3872        1207 :     {
    3873             :         MOZ_ASSERT(pc->sc()->hasExplicitUseStrict(),
    3874           0 :                    "strict mode should only change when a 'use strict' directive is present");
    3875             : 
    3876             :         PropertyName* propertyName = fun->explicitName()->asPropertyName();
    3877           0 :         YieldHandling nameYieldHandling;
    3878             :         if (kind == FunctionSyntaxKind::Expression) {
    3879           0 :             // Named lambda has binding inside it.
    3880             :             nameYieldHandling = bodyYieldHandling;
    3881           0 :         } else {
    3882             :             // Otherwise YieldHandling cannot be checked at this point
    3883             :             // because of different context.
    3884             :             // It should already be checked before this point.
    3885             :             nameYieldHandling = YieldIsName;
    3886             :         }
    3887             : 
    3888             :         // We already use the correct await-handling at this point, therefore
    3889             :         // we don't need call AutoAwaitIsKeyword here.
    3890             : 
    3891             :         uint32_t nameOffset = handler.getFunctionNameOffset(*pn, anyChars);
    3892           0 :         if (!checkBindingIdentifier(propertyName, nameOffset, nameYieldHandling))
    3893           0 :             return false;
    3894             :     }
    3895             : 
    3896             :     if (bodyType == StatementListBody) {
    3897       13057 :         MUST_MATCH_TOKEN_MOD_WITH_REPORT(TokenKind::Rc, TokenStream::Operand,
    3898       12017 :                                          reportMissingClosing(JSMSG_CURLY_AFTER_BODY,
    3899             :                                                               JSMSG_CURLY_OPENED, openedPos));
    3900             :         funbox->setEnd(anyChars);
    3901       12017 :     } else {
    3902             :         MOZ_ASSERT(kind == FunctionSyntaxKind::Arrow);
    3903        1040 : 
    3904             :         if (anyChars.hadError())
    3905           0 :             return false;
    3906             :         funbox->setEnd(anyChars);
    3907        2080 :         if (kind == FunctionSyntaxKind::Statement && !matchOrInsertSemicolon())
    3908        1040 :             return false;
    3909             :     }
    3910             : 
    3911             :     if (IsMethodDefinitionKind(kind) && pc->superScopeNeedsHomeObject())
    3912       13057 :         funbox->setNeedsHomeObject();
    3913           0 : 
    3914             :     if (!finishFunction(isStandaloneFunction))
    3915           0 :         return false;
    3916             : 
    3917             :     handler.setEndPosition(body, pos().begin);
    3918       26114 :     handler.setEndPosition(*pn, pos().end);
    3919           0 :     handler.setFunctionBody(*pn, body);
    3920           0 : 
    3921             :     return true;
    3922       13057 : }
    3923             : 
    3924             : template <class ParseHandler, typename CharT>
    3925             : typename ParseHandler::Node
    3926             : GeneralParser<ParseHandler, CharT>::functionStmt(uint32_t toStringStart,
    3927           0 :                                                  YieldHandling yieldHandling,
    3928             :                                                  DefaultHandling defaultHandling,
    3929             :                                                  FunctionAsyncKind asyncKind)
    3930             : {
    3931             :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Function));
    3932           0 : 
    3933             :     // In sloppy mode, Annex B.3.2 allows labelled function declarations.
    3934             :     // Otherwise it's a parse error.
    3935             :     ParseContext::Statement* declaredInStmt = pc->innermostStatement();
    3936        1635 :     if (declaredInStmt && declaredInStmt->kind() == StatementKind::Label) {
    3937        1635 :         MOZ_ASSERT(!pc->sc()->strict(),
    3938           0 :                    "labeled functions shouldn't be parsed in strict mode");
    3939             : 
    3940             :         // Find the innermost non-label statement.  Report an error if it's
    3941             :         // unbraced: functions can't appear in it.  Otherwise the statement
    3942             :         // (or its absence) determines the scope the function's bound in.
    3943             :         while (declaredInStmt && declaredInStmt->kind() == StatementKind::Label)
    3944           0 :             declaredInStmt = declaredInStmt->enclosing();
    3945           0 : 
    3946             :         if (declaredInStmt && !StatementKindIsBraced(declaredInStmt->kind())) {
    3947           0 :             error(JSMSG_SLOPPY_FUNCTION_LABEL);
    3948           0 :             return null();
    3949           0 :         }
    3950             :     }
    3951             : 
    3952             :     TokenKind tt;
    3953             :     if (!tokenStream.getToken(&tt))
    3954        1635 :         return null();
    3955             : 
    3956             :     GeneratorKind generatorKind = GeneratorKind::NotGenerator;
    3957           0 :     if (tt == TokenKind::Mul) {
    3958        1635 :         generatorKind = GeneratorKind::Generator;
    3959           0 :         if (!tokenStream.getToken(&tt))
    3960           0 :             return null();
    3961             :     }
    3962             : 
    3963             :     RootedPropertyName name(context);
    3964        4905 :     if (TokenKindIsPossibleIdentifier(tt)) {
    3965        3270 :         name = bindingIdentifier(yieldHandling);
    3966           0 :         if (!name)
    3967        1635 :             return null();
    3968             :     } else if (defaultHandling == AllowDefaultName) {
    3969           0 :         name = context->names().default_;
    3970           0 :         anyChars.ungetToken();
    3971           0 :     } else {
    3972             :         /* Unnamed function expressions are forbidden in statement context. */
    3973             :         error(JSMSG_UNNAMED_FUNCTION_STMT);
    3974           0 :         return null();
    3975           0 :     }
    3976             : 
    3977             :     // Note the declared name and check for early errors.
    3978             :     DeclarationKind kind;
    3979             :     if (declaredInStmt) {
    3980        1635 :         MOZ_ASSERT(declaredInStmt->kind() != StatementKind::Label);
    3981           0 :         MOZ_ASSERT(StatementKindIsBraced(declaredInStmt->kind()));
    3982           0 : 
    3983             :         kind = (!pc->sc()->strict() &&
    3984           0 :                 generatorKind == GeneratorKind::NotGenerator &&
    3985           0 :                 asyncKind == FunctionAsyncKind::SyncFunction)
    3986             :                 ? DeclarationKind::SloppyLexicalFunction
    3987           0 :                 : DeclarationKind::LexicalFunction;
    3988             :     } else {
    3989             :         kind = pc->atModuleLevel()
    3990        1635 :                ? DeclarationKind::ModuleBodyLevelFunction
    3991        1635 :                : DeclarationKind::BodyLevelFunction;
    3992             :     }
    3993             : 
    3994             :     if (!noteDeclaredName(name, kind, pos()))
    3995        4905 :         return null();
    3996             : 
    3997             :     Node pn = handler.newFunctionStatement(pos());
    3998        4905 :     if (!pn)
    3999           0 :         return null();
    4000             : 
    4001             :     // Under sloppy mode, try Annex B.3.3 semantics. If making an additional
    4002             :     // 'var' binding of the same name does not throw an early error, do so.
    4003             :     // This 'var' binding would be assigned the function object when its
    4004             :     // declaration is reached, not at the start of the block.
    4005             :     //
    4006             :     // This semantics is implemented upon Scope exit in
    4007             :     // Scope::propagateAndMarkAnnexBFunctionBoxes.
    4008             :     bool tryAnnexB = kind == DeclarationKind::SloppyLexicalFunction;
    4009        1635 : 
    4010             :     YieldHandling newYieldHandling = GetYieldHandling(generatorKind);
    4011           0 :     return functionDefinition(pn, toStringStart, InAllowed, newYieldHandling, name,
    4012        4905 :                               FunctionSyntaxKind::Statement, generatorKind, asyncKind, tryAnnexB);
    4013        1635 : }
    4014             : 
    4015             : template <class ParseHandler, typename CharT>
    4016             : typename ParseHandler::Node
    4017             : GeneralParser<ParseHandler, CharT>::functionExpr(uint32_t toStringStart,
    4018        2165 :                                                  InvokedPrediction invoked,
    4019             :                                                  FunctionAsyncKind asyncKind)
    4020             : {
    4021             :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Function));
    4022        4330 : 
    4023             :     AutoAwaitIsKeyword<ParseHandler, CharT> awaitIsKeyword(this, GetAwaitHandling(asyncKind));
    4024           0 :     GeneratorKind generatorKind = GeneratorKind::NotGenerator;
    4025           0 :     TokenKind tt;
    4026             :     if (!tokenStream.getToken(&tt))
    4027        2165 :         return null();
    4028             : 
    4029             :     if (tt == TokenKind::Mul) {
    4030           0 :         generatorKind = GeneratorKind::Generator;
    4031           4 :         if (!tokenStream.getToken(&tt))
    4032           4 :             return null();
    4033             :     }
    4034             : 
    4035             :     YieldHandling yieldHandling = GetYieldHandling(generatorKind);
    4036           0 : 
    4037             :     RootedPropertyName name(context);
    4038        6495 :     if (TokenKindIsPossibleIdentifier(tt)) {
    4039           0 :         name = bindingIdentifier(yieldHandling);
    4040        2466 :         if (!name)
    4041        1233 :             return null();
    4042             :     } else {
    4043             :         anyChars.ungetToken();
    4044           0 :     }
    4045             : 
    4046             :     Node pn = handler.newFunctionExpression(pos());
    4047        6495 :     if (!pn)
    4048           0 :         return null();
    4049             : 
    4050             :     if (invoked)
    4051           0 :         pn = handler.setLikelyIIFE(pn);
    4052           0 : 
    4053             :     return functionDefinition(pn, toStringStart, InAllowed, yieldHandling, name,
    4054        4330 :                               FunctionSyntaxKind::Expression, generatorKind, asyncKind);
    4055        2165 : }
    4056             : 
    4057             : /*
    4058             :  * Return true if this node, known to be an unparenthesized string literal,
    4059             :  * could be the string of a directive in a Directive Prologue. Directive
    4060             :  * strings never contain escape sequences or line continuations.
    4061             :  * isEscapeFreeStringLiteral, below, checks whether the node itself could be
    4062             :  * a directive.
    4063             :  */
    4064             : static inline bool
    4065             : IsEscapeFreeStringLiteral(const TokenPos& pos, JSAtom* str)
    4066             : {
    4067             :     /*
    4068             :      * If the string's length in the source code is its length as a value,
    4069             :      * accounting for the quotes, then it must not contain any escape
    4070             :      * sequences or line continuations.
    4071             :      */
    4072             :     return pos.begin + str->length() + 2 == pos.end;
    4073         506 : }
    4074             : 
    4075             : template <typename CharT>
    4076             : bool
    4077             : Parser<SyntaxParseHandler, CharT>::asmJS(Node list)
    4078           0 : {
    4079             :     // While asm.js could technically be validated and compiled during syntax
    4080             :     // parsing, we have no guarantee that some later JS wouldn't abort the
    4081             :     // syntax parse and cause us to re-parse (and re-compile) the asm.js module.
    4082             :     // For simplicity, unconditionally abort the syntax parse when "use asm" is
    4083             :     // encountered so that asm.js is always validated/compiled exactly once
    4084             :     // during a full parse.
    4085             :     MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
    4086           0 : 
    4087             :     // Record that the current script source constains some AsmJS, to disable
    4088             :     // any incremental encoder, as AsmJS cannot be encoded with XDR at the
    4089             :     // moment.
    4090             :     if (ss)
    4091           0 :         ss->setContainsAsmJS();
    4092           0 :     return false;
    4093           0 : }
    4094             : 
    4095             : template <typename CharT>
    4096             : bool
    4097             : Parser<FullParseHandler, CharT>::asmJS(Node list)
    4098           0 : {
    4099             :     // Disable syntax parsing in anything nested inside the asm.js module.
    4100             :     disableSyntaxParser();
    4101           0 : 
    4102             :     // We should be encountering the "use asm" directive for the first time; if
    4103             :     // the directive is already, we must have failed asm.js validation and we're
    4104             :     // reparsing. In that case, don't try to validate again. A non-null
    4105             :     // newDirectives means we're not in a normal function.
    4106             :     if (!pc->newDirectives || pc->newDirectives->asmJS())
    4107           0 :         return true;
    4108             : 
    4109             :     // If there is no ScriptSource, then we are doing a non-compiling parse and
    4110             :     // so we shouldn't (and can't, without a ScriptSource) compile.
    4111             :     if (ss == nullptr)
    4112           0 :         return true;
    4113             : 
    4114             :     ss->setContainsAsmJS();
    4115           0 :     pc->functionBox()->useAsm = true;
    4116           0 : 
    4117             :     // Attempt to validate and compile this asm.js module. On success, the
    4118             :     // tokenStream has been advanced to the closing }. On failure, the
    4119             :     // tokenStream is in an indeterminate state and we must reparse the
    4120             :     // function from the beginning. Reparsing is triggered by marking that a
    4121             :     // new directive has been encountered and returning 'false'.
    4122             :     bool validated;
    4123             :     if (!CompileAsmJS(context, *this, list, &validated))
    4124           0 :         return false;
    4125             :     if (!validated) {
    4126           0 :         pc->newDirectives->setAsmJS();
    4127           0 :         return false;
    4128           0 :     }
    4129             : 
    4130             :     return true;
    4131             : }
    4132             : 
    4133             : template <class ParseHandler, typename CharT>
    4134             : inline bool
    4135             : GeneralParser<ParseHandler, CharT>::asmJS(Node list)
    4136           0 : {
    4137             :     return asFinalParser()->asmJS(list);
    4138           0 : }
    4139             : 
    4140             : /*
    4141             :  * Recognize Directive Prologue members and directives. Assuming |pn| is a
    4142             :  * candidate for membership in a directive prologue, recognize directives and
    4143             :  * set |pc|'s flags accordingly. If |pn| is indeed part of a prologue, set its
    4144             :  * |pn_prologue| flag.
    4145             :  *
    4146             :  * Note that the following is a strict mode function:
    4147             :  *
    4148             :  * function foo() {
    4149             :  *   "blah" // inserted semi colon
    4150             :  *        "blurgh"
    4151             :  *   "use\x20loose"
    4152             :  *   "use strict"
    4153             :  * }
    4154             :  *
    4155             :  * That is, even though "use\x20loose" can never be a directive, now or in the
    4156             :  * future (because of the hex escape), the Directive Prologue extends through it
    4157             :  * to the "use strict" statement, which is indeed a directive.
    4158             :  */
    4159             : template <class ParseHandler, typename CharT>
    4160             : bool
    4161             : GeneralParser<ParseHandler, CharT>::maybeParseDirective(Node list, Node possibleDirective,
    4162       12482 :                                                         bool* cont)
    4163             : {
    4164             :     TokenPos directivePos;
    4165       12482 :     JSAtom* directive = handler.isStringExprStatement(possibleDirective, &directivePos);
    4166       24964 : 
    4167             :     *cont = !!directive;
    4168       12482 :     if (!*cont)
    4169       12482 :         return true;
    4170             : 
    4171             :     if (IsEscapeFreeStringLiteral(directivePos, directive)) {
    4172         253 :         // Mark this statement as being a possibly legitimate part of a
    4173             :         // directive prologue, so the bytecode emitter won't warn about it being
    4174             :         // useless code. (We mustn't just omit the statement entirely yet, as it
    4175             :         // could be producing the value of an eval or JSScript execution.)
    4176             :         //
    4177             :         // Note that even if the string isn't one we recognize as a directive,
    4178             :         // the emitter still shouldn't flag it as useless, as it could become a
    4179             :         // directive in the future. We don't want to interfere with people
    4180             :         // taking advantage of directive-prologue-enabled features that appear
    4181             :         // in other browsers first.
    4182             :         handler.setInDirectivePrologue(possibleDirective);
    4183         253 : 
    4184             :         if (directive == context->names().useStrict) {
    4185         759 :             // Functions with non-simple parameter lists (destructuring,
    4186             :             // default or rest parameters) must not contain a "use strict"
    4187             :             // directive.
    4188             :             if (pc->isFunctionBox()) {
    4189         502 :                 FunctionBox* funbox = pc->functionBox();
    4190          74 :                 if (!funbox->hasSimpleParameterList()) {
    4191          37 :                     const char* parameterKind = funbox->hasDestructuringArgs
    4192           0 :                                                 ? "destructuring"
    4193             :                                                 : funbox->hasParameterExprs
    4194           0 :                                                 ? "default"
    4195             :                                                 : "rest";
    4196           0 :                     errorAt(directivePos.begin, JSMSG_STRICT_NON_SIMPLE_PARAMS, parameterKind);
    4197           0 :                     return false;
    4198           0 :                 }
    4199             :             }
    4200             : 
    4201             :             // We're going to be in strict mode. Note that this scope explicitly
    4202             :             // had "use strict";
    4203             :             pc->sc()->setExplicitUseStrict();
    4204           0 :             if (!pc->sc()->strict()) {
    4205         502 :                 // We keep track of the one possible strict violation that could
    4206             :                 // occur in the directive prologue -- octal escapes -- and
    4207             :                 // complain now.
    4208             :                 if (anyChars.sawOctalEscape()) {
    4209           0 :                     error(JSMSG_DEPRECATED_OCTAL);
    4210           0 :                     return false;
    4211           0 :                 }
    4212             :                 pc->sc()->strictScript = true;
    4213          77 :             }
    4214             :         } else if (directive == context->names().useAsm) {
    4215           6 :             if (pc->isFunctionBox())
    4216           0 :                 return asmJS(list);
    4217           0 :             return warningAt(directivePos.begin, JSMSG_USE_ASM_DIRECTIVE_FAIL);
    4218           0 :         }
    4219             :     }
    4220             :     return true;
    4221             : }
    4222             : 
    4223             : template <class ParseHandler, typename CharT>
    4224             : typename ParseHandler::Node
    4225             : GeneralParser<ParseHandler, CharT>::statementList(YieldHandling yieldHandling)
    4226       28756 : {
    4227             :     if (!CheckRecursionLimit(context))
    4228           0 :         return null();
    4229             : 
    4230             :     Node pn = handler.newStatementList(pos());
    4231       86268 :     if (!pn)
    4232       28756 :         return null();
    4233             : 
    4234             :     bool canHaveDirectives = pc->atBodyLevel();
    4235       57512 :     if (canHaveDirectives)
    4236       28756 :         anyChars.clearSawOctalEscape();
    4237       12427 :     bool afterReturn = false;
    4238             :     bool warnedAboutStatementsAfterReturn = false;
    4239             :     uint32_t statementBegin = 0;
    4240             :     for (;;) {
    4241       72910 :         TokenKind tt = TokenKind::Eof;
    4242      101666 :         if (!tokenStream.peekToken(&tt, TokenStream::Operand)) {
    4243           0 :             if (anyChars.isEOF())
    4244           0 :                 isUnexpectedEOF_ = true;
    4245           0 :             return null();
    4246           0 :         }
    4247             :         if (tt == TokenKind::Eof || tt == TokenKind::Rc) {
    4248           0 :             TokenPos pos;
    4249           0 :             if (!tokenStream.peekTokenPos(&pos, TokenStream::Operand)) {
    4250       28756 :                 return null();
    4251           0 :             }
    4252             :             handler.setListEndPosition(pn, pos);
    4253           0 :             break;
    4254           0 :         }
    4255             :         if (afterReturn) {
    4256           0 :             if (!tokenStream.peekOffset(&statementBegin, TokenStream::Operand))
    4257           0 :                 return null();
    4258             :         }
    4259             :         Node next = statementListItem(yieldHandling, canHaveDirectives);
    4260           0 :         if (!next) {
    4261           0 :             if (anyChars.isEOF())
    4262           0 :                 isUnexpectedEOF_ = true;
    4263           0 :             return null();
    4264             :         }
    4265             :         if (!warnedAboutStatementsAfterReturn) {
    4266           0 :             if (afterReturn) {
    4267       72910 :                 if (!handler.isStatementPermittedAfterReturnStatement(next)) {
    4268           0 :                     if (!warningAt(statementBegin, JSMSG_STMT_AFTER_RETURN))
    4269           0 :                         return null();
    4270             : 
    4271             :                     warnedAboutStatementsAfterReturn = true;
    4272             :                 }
    4273             :             } else if (handler.isReturnStatement(next)) {
    4274           0 :                 afterReturn = true;
    4275           0 :             }
    4276             :         }
    4277             : 
    4278             :         if (canHaveDirectives) {
    4279           0 :             if (!maybeParseDirective(pn, next, &canHaveDirectives))
    4280           0 :                 return null();
    4281             :         }
    4282             : 
    4283             :         handler.addStatementToList(pn, next);
    4284       72910 :     }
    4285             : 
    4286             :     return pn;
    4287           0 : }
    4288             : 
    4289             : template <class ParseHandler, typename CharT>
    4290             : typename ParseHandler::Node
    4291             : GeneralParser<ParseHandler, CharT>::condition(InHandling inHandling, YieldHandling yieldHandling)
    4292           0 : {
    4293             :     MUST_MATCH_TOKEN(TokenKind::Lp, JSMSG_PAREN_BEFORE_COND);
    4294       14113 : 
    4295             :     Node pn = exprInParens(inHandling, yieldHandling, TripledotProhibited);
    4296           0 :     if (!pn)
    4297       14113 :         return null();
    4298             : 
    4299             :     MUST_MATCH_TOKEN_MOD(TokenKind::Rp, TokenStream::Operand, JSMSG_PAREN_AFTER_COND);
    4300       14113 : 
    4301             :     /* Check for (a = b) and warn about possible (a == b) mistype. */
    4302             :     if (handler.isUnparenthesizedAssignment(pn)) {
    4303       14113 :         if (!extraWarning(JSMSG_EQUAL_AS_ASSIGN))
    4304           0 :             return null();
    4305             :     }
    4306             :     return pn;
    4307             : }
    4308             : 
    4309             : template <class ParseHandler, typename CharT>
    4310             : bool
    4311             : GeneralParser<ParseHandler, CharT>::matchLabel(YieldHandling yieldHandling,
    4312           0 :                                                MutableHandle<PropertyName*> label)
    4313             : {
    4314             :     TokenKind tt = TokenKind::Eof;
    4315           0 :     if (!tokenStream.peekTokenSameLine(&tt, TokenStream::Operand))
    4316           0 :         return false;
    4317             : 
    4318             :     if (TokenKindIsPossibleIdentifier(tt)) {
    4319        3056 :         tokenStream.consumeKnownToken(tt, TokenStream::Operand);
    4320           0 : 
    4321             :         label.set(labelIdentifier(yieldHandling));
    4322           0 :         if (!label)
    4323           0 :             return false;
    4324             :     } else {
    4325             :         label.set(nullptr);
    4326        1528 :     }
    4327             :     return true;
    4328             : }
    4329             : 
    4330             : template <class ParseHandler, typename CharT>
    4331             : GeneralParser<ParseHandler, CharT>::PossibleError::PossibleError(GeneralParser<ParseHandler, CharT>& parser)
    4332           0 :   : parser_(parser)
    4333      515640 : {}
    4334           0 : 
    4335             : template <class ParseHandler, typename CharT>
    4336             : typename GeneralParser<ParseHandler, CharT>::PossibleError::Error&
    4337             : GeneralParser<ParseHandler, CharT>::PossibleError::error(ErrorKind kind)
    4338           0 : {
    4339             :     if (kind == ErrorKind::Expression)
    4340      430047 :         return exprError_;
    4341      139881 :     if (kind == ErrorKind::Destructuring)
    4342      290166 :         return destructuringError_;
    4343      172917 :     MOZ_ASSERT(kind == ErrorKind::DestructuringWarning);
    4344           0 :     return destructuringWarning_;
    4345           0 : }
    4346             : 
    4347             : template <class ParseHandler, typename CharT>
    4348             : void
    4349             : GeneralParser<ParseHandler, CharT>::PossibleError::setResolved(ErrorKind kind)
    4350           0 : {
    4351             :     error(kind).state_ = ErrorState::None;
    4352           0 : }
    4353           0 : 
    4354             : template <class ParseHandler, typename CharT>
    4355             : bool
    4356             : GeneralParser<ParseHandler, CharT>::PossibleError::hasError(ErrorKind kind)
    4357           0 : {
    4358             :     return error(kind).state_ == ErrorState::Pending;
    4359      189230 : }
    4360             : 
    4361             : template <class ParseHandler, typename CharT>
    4362             : bool
    4363             : GeneralParser<ParseHandler, CharT>::PossibleError::hasPendingDestructuringError()
    4364           0 : {
    4365             :     return hasError(ErrorKind::Destructuring);
    4366       16719 : }
    4367             : 
    4368             : template <class ParseHandler, typename CharT>
    4369             : void
    4370             : GeneralParser<ParseHandler, CharT>::PossibleError::setPending(ErrorKind kind, const TokenPos& pos,
    4371           0 :                                                               unsigned errorNumber)
    4372             : {
    4373             :     // Don't overwrite a previously recorded error.
    4374             :     if (hasError(kind))
    4375        7885 :         return;
    4376             : 
    4377             :     // If we report an error later, we'll do it from the position where we set
    4378             :     // the state to pending.
    4379             :     Error& err = error(kind);
    4380        3772 :     err.offset_ = pos.begin;
    4381        3772 :     err.errorNumber_ = errorNumber;
    4382        3772 :     err.state_ = ErrorState::Pending;
    4383           0 : }
    4384             : 
    4385             : template <class ParseHandler, typename CharT>
    4386             : void
    4387             : GeneralParser<ParseHandler, CharT>::PossibleError::setPendingDestructuringErrorAt(const TokenPos& pos,
    4388        7885 :                                                                                   unsigned errorNumber)
    4389             : {
    4390             :     setPending(ErrorKind::Destructuring, pos, errorNumber);
    4391        7885 : }
    4392           0 : 
    4393             : template <class ParseHandler, typename CharT>
    4394             : void
    4395             : GeneralParser<ParseHandler, CharT>::PossibleError::setPendingDestructuringWarningAt(const TokenPos& pos,
    4396           0 :                                                                                     unsigned errorNumber)
    4397             : {
    4398             :     setPending(ErrorKind::DestructuringWarning, pos, errorNumber);
    4399           0 : }
    4400           0 : 
    4401             : template <class ParseHandler, typename CharT>
    4402             : void
    4403             : GeneralParser<ParseHandler, CharT>::PossibleError::setPendingExpressionErrorAt(const TokenPos& pos,
    4404           0 :                                                                                unsigned errorNumber)
    4405             : {
    4406             :     setPending(ErrorKind::Expression, pos, errorNumber);
    4407           0 : }
    4408           0 : 
    4409             : template <class ParseHandler, typename CharT>
    4410             : bool
    4411             : GeneralParser<ParseHandler, CharT>::PossibleError::checkForError(ErrorKind kind)
    4412           1 : {
    4413             :     if (!hasError(kind))
    4414      117248 :         return true;
    4415             : 
    4416             :     Error& err = error(kind);
    4417           0 :     parser_.errorAt(err.offset_, err.errorNumber_);
    4418           0 :     return false;
    4419           0 : }
    4420             : 
    4421             : template <class ParseHandler, typename CharT>
    4422             : bool
    4423             : GeneralParser<ParseHandler, CharT>::PossibleError::checkForWarning(ErrorKind kind)
    4424           0 : {
    4425             :     if (!hasError(kind))
    4426           0 :         return true;
    4427             : 
    4428             :     Error& err = error(kind);
    4429           0 :     return parser_.extraWarningAt(err.offset_, err.errorNumber_);
    4430           0 : }
    4431             : 
    4432             : template <class ParseHandler, typename CharT>
    4433             : bool
    4434             : GeneralParser<ParseHandler, CharT>::PossibleError::checkForDestructuringErrorOrWarning()
    4435          29 : {
    4436             :     // Clear pending expression error, because we're definitely not in an
    4437             :     // expression context.
    4438             :     setResolved(ErrorKind::Expression);
    4439          29 : 
    4440             :     // Report any pending destructuring error or warning.
    4441             :     return checkForError(ErrorKind::Destructuring) &&
    4442           1 :            checkForWarning(ErrorKind::DestructuringWarning);
    4443          58 : }
    4444             : 
    4445             : template <class ParseHandler, typename CharT>
    4446             : bool
    4447             : GeneralParser<ParseHandler, CharT>::PossibleError::checkForExpressionError()
    4448      117220 : {
    4449             :     // Clear pending destructuring error or warning, because we're definitely
    4450             :     // not in a destructuring context.
    4451             :     setResolved(ErrorKind::Destructuring);
    4452      117220 :     setResolved(ErrorKind::DestructuringWarning);
    4453      117220 : 
    4454             :     // Report any pending expression error.
    4455             :     return checkForError(ErrorKind::Expression);
    4456      117219 : }
    4457             : 
    4458             : template <class ParseHandler, typename CharT>
    4459             : void
    4460             : GeneralParser<ParseHandler, CharT>::PossibleError::transferErrorTo(ErrorKind kind,
    4461       45266 :                                                                    PossibleError* other)
    4462             : {
    4463             :     if (hasError(kind) && !other->hasError(kind)) {
    4464           0 :         Error& err = error(kind);
    4465           0 :         Error& otherErr = other->error(kind);
    4466        1288 :         otherErr.offset_ = err.offset_;
    4467        1288 :         otherErr.errorNumber_ = err.errorNumber_;
    4468           0 :         otherErr.state_ = err.state_;
    4469        1288 :     }
    4470             : }
    4471       45266 : 
    4472             : template <class ParseHandler, typename CharT>
    4473             : void
    4474             : GeneralParser<ParseHandler, CharT>::PossibleError::transferErrorsTo(PossibleError* other)
    4475       22633 : {
    4476             :     MOZ_ASSERT(other);
    4477           0 :     MOZ_ASSERT(this != other);
    4478           0 :     MOZ_ASSERT(&parser_ == &other->parser_,
    4479           0 :                "Can't transfer fields to an instance which belongs to a different parser");
    4480             : 
    4481             :     transferErrorTo(ErrorKind::Destructuring, other);
    4482       22633 :     transferErrorTo(ErrorKind::Expression, other);
    4483           0 : }
    4484       22633 : 
    4485             : template <class ParseHandler, typename CharT>
    4486             : typename ParseHandler::Node
    4487             : GeneralParser<ParseHandler, CharT>::bindingInitializer(Node lhs, DeclarationKind kind,
    4488          41 :                                                        YieldHandling yieldHandling)
    4489             : {
    4490             :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Assign));
    4491           0 : 
    4492             :     if (kind == DeclarationKind::FormalParameter)
    4493          41 :         pc->functionBox()->hasParameterExprs = true;
    4494           0 : 
    4495             :     Node rhs = assignExpr(InAllowed, yieldHandling, TripledotProhibited);
    4496           0 :     if (!rhs)
    4497          41 :         return null();
    4498             : 
    4499             :     Node assign = handler.newAssignment(ParseNodeKind::Assign, lhs, rhs);
    4500           0 :     if (!assign)
    4501          41 :         return null();
    4502             : 
    4503             :     if (foldConstants && !FoldConstants(context, &assign, this))
    4504          41 :         return null();
    4505             : 
    4506             :     return assign;
    4507          41 : }
    4508             : 
    4509             : template <class ParseHandler, typename CharT>
    4510             : typename ParseHandler::Node
    4511             : GeneralParser<ParseHandler, CharT>::bindingIdentifier(DeclarationKind kind,
    4512           0 :                                                       YieldHandling yieldHandling)
    4513             : {
    4514             :     RootedPropertyName name(context, bindingIdentifier(yieldHandling));
    4515        5132 :     if (!name)
    4516           0 :         return null();
    4517             : 
    4518             :     Node binding = newName(name);
    4519           0 :     if (!binding || !noteDeclaredName(name, kind, pos()))
    4520        7698 :         return null();
    4521             : 
    4522             :     return binding;
    4523        2566 : }
    4524             : 
    4525             : template <class ParseHandler, typename CharT>
    4526             : typename ParseHandler::Node
    4527             : GeneralParser<ParseHandler, CharT>::bindingIdentifierOrPattern(DeclarationKind kind,
    4528           0 :                                                                YieldHandling yieldHandling,
    4529             :                                                                TokenKind tt)
    4530             : {
    4531             :     if (tt == TokenKind::Lb)
    4532           0 :         return arrayBindingPattern(kind, yieldHandling);
    4533           8 : 
    4534             :     if (tt == TokenKind::Lc)
    4535           0 :         return objectBindingPattern(kind, yieldHandling);
    4536           8 : 
    4537             :     if (!TokenKindIsPossibleIdentifierName(tt)) {
    4538         601 :         error(JSMSG_NO_VARIABLE_NAME);
    4539           0 :         return null();
    4540           0 :     }
    4541             : 
    4542             :     return bindingIdentifier(kind, yieldHandling);
    4543         601 : }
    4544             : 
    4545             : template <class ParseHandler, typename CharT>
    4546             : typename ParseHandler::Node
    4547             : GeneralParser<ParseHandler, CharT>::objectBindingPattern(DeclarationKind kind,
    4548           0 :                                                          YieldHandling yieldHandling)
    4549             : {
    4550             :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Lc));
    4551           0 : 
    4552             :     if (!CheckRecursionLimit(context))
    4553         559 :         return null();
    4554             : 
    4555             :     uint32_t begin = pos().begin;
    4556        1118 :     Node literal = handler.newObjectLiteral(begin);
    4557        1118 :     if (!literal)
    4558         559 :         return null();
    4559             : 
    4560             :     Maybe<DeclarationKind> declKind = Some(kind);
    4561         559 :     RootedAtom propAtom(context);
    4562        1118 :     for (;;) {
    4563           0 :         TokenKind tt;
    4564             :         if (!tokenStream.peekToken(&tt))
    4565           0 :             return null();
    4566           0 :         if (tt == TokenKind::Rc) {
    4567        1107 :             anyChars.addModifierException(TokenStream::OperandIsNone);
    4568           0 :             break;
    4569           0 :         }
    4570             : 
    4571             :         if (tt == TokenKind::TripleDot) {
    4572        1065 :             tokenStream.consumeKnownToken(TokenKind::TripleDot);
    4573           0 :             uint32_t begin = pos().begin;
    4574           0 : 
    4575             :             TokenKind tt;
    4576             :             if (!tokenStream.getToken(&tt))
    4577           0 :                 return null();
    4578           0 : 
    4579             :             if (!TokenKindIsPossibleIdentifierName(tt)) {
    4580           0 :                 error(JSMSG_NO_VARIABLE_NAME);
    4581           0 :                 return null();
    4582           0 :             }
    4583             : 
    4584             :             Node inner = bindingIdentifier(kind, yieldHandling);
    4585           0 :             if (!inner)
    4586           0 :                 return null();
    4587             : 
    4588             :             if (!handler.addSpreadProperty(literal, begin, inner))
    4589           0 :                 return null();
    4590             :         } else {
    4591             :             TokenPos namePos = anyChars.nextToken().pos;
    4592           0 : 
    4593             :             PropertyType propType;
    4594             :             Node propName = propertyName(yieldHandling, declKind, literal, &propType, &propAtom);
    4595        1065 :             if (!propName)
    4596        1065 :                 return null();
    4597           0 : 
    4598             :             if (propType == PropertyType::Normal) {
    4599        1065 :                 // Handle e.g., |var {p: x} = o| and |var {p: x=0} = o|.
    4600             : 
    4601             :                 if (!tokenStream.getToken(&tt, TokenStream::Operand))
    4602         102 :                     return null();
    4603           0 : 
    4604             :                 Node binding = bindingIdentifierOrPattern(kind, yieldHandling, tt);
    4605         102 :                 if (!binding)
    4606         102 :                     return null();
    4607             : 
    4608             :                 bool hasInitializer;
    4609             :                 if (!tokenStream.matchToken(&hasInitializer, TokenKind::Assign, TokenStream::Operand))
    4610         102 :                     return null();
    4611             : 
    4612             :                 Node bindingExpr = hasInitializer
    4613             :                                    ? bindingInitializer(binding, kind, yieldHandling)
    4614           0 :                                    : binding;
    4615           0 :                 if (!bindingExpr)
    4616         102 :                     return null();
    4617             : 
    4618             :                 if (!handler.addPropertyDefinition(literal, propName, bindingExpr))
    4619         102 :                     return null();
    4620             :             } else if (propType == PropertyType::Shorthand) {
    4621         963 :                 // Handle e.g., |var {x, y} = o| as destructuring shorthand
    4622             :                 // for |var {x: x, y: y} = o|.
    4623             :                 MOZ_ASSERT(TokenKindIsPossibleIdentifierName(tt));
    4624         927 : 
    4625             :                 Node binding = bindingIdentifier(kind, yieldHandling);
    4626           0 :                 if (!binding)
    4627           0 :                     return null();
    4628             : 
    4629             :                 if (!handler.addShorthand(literal, propName, binding))
    4630         927 :                     return null();
    4631             :             } else if (propType == PropertyType::CoverInitializedName) {
    4632          36 :                 // Handle e.g., |var {x=1, y=2} = o| as destructuring
    4633             :                 // shorthand with default values.
    4634             :                 MOZ_ASSERT(TokenKindIsPossibleIdentifierName(tt));
    4635          36 : 
    4636             :                 Node binding = bindingIdentifier(kind, yieldHandling);
    4637          36 :                 if (!binding)
    4638           0 :                     return null();
    4639             : 
    4640             :                 tokenStream.consumeKnownToken(TokenKind::Assign);
    4641          36 : 
    4642             :                 Node bindingExpr = bindingInitializer(binding, kind, yieldHandling);
    4643          36 :                 if (!bindingExpr)
    4644           0 :                     return null();
    4645             : 
    4646             :                 if (!handler.addPropertyDefinition(literal, propName, bindingExpr))
    4647           0 :                     return null();
    4648             :             } else {
    4649             :                 errorAt(namePos.begin, JSMSG_NO_VARIABLE_NAME);
    4650           0 :                 return null();
    4651           0 :             }
    4652             :         }
    4653             : 
    4654             :         bool matched;
    4655             :         if (!tokenStream.matchToken(&matched, TokenKind::Comma, TokenStream::Operand))
    4656           0 :             return null();
    4657             :         if (!matched)
    4658        1065 :             break;
    4659             :         if (tt == TokenKind::TripleDot) {
    4660         548 :             error(JSMSG_REST_WITH_COMMA);
    4661           0 :             return null();
    4662           0 :         }
    4663             :     }
    4664             : 
    4665             :     MUST_MATCH_TOKEN_MOD_WITH_REPORT(TokenKind::Rc, TokenStream::Operand,
    4666         559 :                                      reportMissingClosing(JSMSG_CURLY_AFTER_LIST,
    4667             :                                                           JSMSG_CURLY_OPENED, begin));
    4668             : 
    4669             :     handler.setEndPosition(literal, pos().end);
    4670           0 :     return literal;
    4671         559 : }
    4672             : 
    4673             : template <class ParseHandler, typename CharT>
    4674             : typename ParseHandler::Node
    4675             : GeneralParser<ParseHandler, CharT>::arrayBindingPattern(DeclarationKind kind,
    4676         284 :                                                         YieldHandling yieldHandling)
    4677             : {
    4678             :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Lb));
    4679         568 : 
    4680             :     if (!CheckRecursionLimit(context))
    4681         284 :         return null();
    4682             : 
    4683             :     uint32_t begin = pos().begin;
    4684         568 :     Node literal = handler.newArrayLiteral(begin);
    4685         568 :     if (!literal)
    4686         284 :         return null();
    4687             : 
    4688             :      uint32_t index = 0;
    4689           0 :      for (; ; index++) {
    4690         292 :          if (index >= NativeObject::MAX_DENSE_ELEMENTS_COUNT) {
    4691           0 :              error(JSMSG_ARRAY_INIT_TOO_BIG);
    4692           0 :              return null();
    4693           0 :          }
    4694             : 
    4695             :          TokenKind tt;
    4696             :          if (!tokenStream.getToken(&tt))
    4697           0 :              return null();
    4698             : 
    4699             :          if (tt == TokenKind::Rb) {
    4700         576 :              anyChars.ungetToken();
    4701           1 :              anyChars.addModifierException(TokenStream::OperandIsNone);
    4702           0 :              break;
    4703           0 :          }
    4704             : 
    4705             :          if (tt == TokenKind::Comma) {
    4706         552 :              if (!handler.addElision(literal, pos()))
    4707          74 :                  return null();
    4708             :          } else if (tt == TokenKind::TripleDot) {
    4709           0 :              uint32_t begin = pos().begin;
    4710           2 : 
    4711             :              TokenKind tt;
    4712             :              if (!tokenStream.getToken(&tt))
    4713           0 :                  return null();
    4714           0 : 
    4715             :              Node inner = bindingIdentifierOrPattern(kind, yieldHandling, tt);
    4716           1 :              if (!inner)
    4717           1 :                  return null();
    4718             : 
    4719             :              if (!handler.addSpreadElement(literal, begin, inner))
    4720           1 :                  return null();
    4721             :          } else {
    4722             :              Node binding = bindingIdentifierOrPattern(kind, yieldHandling, tt);
    4723         514 :              if (!binding)
    4724         514 :                  return null();
    4725           0 : 
    4726             :              bool hasInitializer;
    4727             :              if (!tokenStream.matchToken(&hasInitializer, TokenKind::Assign, TokenStream::Operand))
    4728           0 :                  return null();
    4729             : 
    4730             :              Node element = hasInitializer
    4731             :                             ? bindingInitializer(binding, kind, yieldHandling)
    4732           0 :                             : binding;
    4733         514 :              if (!element)
    4734         514 :                  return null();
    4735             : 
    4736             :              handler.addArrayElement(literal, element);
    4737           0 :          }
    4738             : 
    4739             :          if (tt != TokenKind::Comma) {
    4740           0 :              // If we didn't already match TokenKind::Comma in above case.
    4741             :              bool matched;
    4742             :              if (!tokenStream.matchToken(&matched, TokenKind::Comma, TokenStream::Operand))
    4743         515 :                  return null();
    4744           0 :              if (!matched)
    4745           0 :                  break;
    4746             : 
    4747             :              if (tt == TokenKind::TripleDot) {
    4748         255 :                  error(JSMSG_REST_WITH_COMMA);
    4749           0 :                  return null();
    4750           0 :              }
    4751             :          }
    4752             :      }
    4753             : 
    4754             :      MUST_MATCH_TOKEN_MOD_WITH_REPORT(TokenKind::Rb, TokenStream::Operand,
    4755           0 :                                       reportMissingClosing(JSMSG_BRACKET_AFTER_LIST,
    4756             :                                                            JSMSG_BRACKET_OPENED, begin));
    4757             : 
    4758             :     handler.setEndPosition(literal, pos().end);
    4759         568 :     return literal;
    4760           0 : }
    4761             : 
    4762             : template <class ParseHandler, typename CharT>
    4763             : typename ParseHandler::Node
    4764             : GeneralParser<ParseHandler, CharT>::destructuringDeclaration(DeclarationKind kind,
    4765         827 :                                                              YieldHandling yieldHandling,
    4766             :                                                              TokenKind tt)
    4767             : {
    4768             :     MOZ_ASSERT(anyChars.isCurrentTokenType(tt));
    4769        1654 :     MOZ_ASSERT(tt == TokenKind::Lb || tt == TokenKind::Lc);
    4770         827 : 
    4771             :     return tt == TokenKind::Lb
    4772             :            ? arrayBindingPattern(kind, yieldHandling)
    4773         827 :            : objectBindingPattern(kind, yieldHandling);
    4774         827 : }
    4775             : 
    4776             : template <class ParseHandler, typename CharT>
    4777             : typename ParseHandler::Node
    4778             : GeneralParser<ParseHandler, CharT>::destructuringDeclarationWithoutYieldOrAwait(DeclarationKind kind,
    4779         108 :                                                                                 YieldHandling yieldHandling,
    4780             :                                                                                 TokenKind tt)
    4781             : {
    4782             :     uint32_t startYieldOffset = pc->lastYieldOffset;
    4783         108 :     uint32_t startAwaitOffset = pc->lastAwaitOffset;
    4784         108 :     Node res = destructuringDeclaration(kind, yieldHandling, tt);
    4785           0 :     if (res) {
    4786           0 :         if (pc->lastYieldOffset != startYieldOffset) {
    4787         108 :             errorAt(pc->lastYieldOffset, JSMSG_YIELD_IN_DEFAULT);
    4788           0 :             return null();
    4789           0 :         }
    4790             :         if (pc->lastAwaitOffset != startAwaitOffset) {
    4791           0 :             errorAt(pc->lastAwaitOffset, JSMSG_AWAIT_IN_DEFAULT);
    4792           0 :             return null();
    4793           0 :         }
    4794             :     }
    4795             :     return res;
    4796             : }
    4797             : 
    4798             : template <class ParseHandler, typename CharT>
    4799             : typename ParseHandler::Node
    4800             : GeneralParser<ParseHandler, CharT>::blockStatement(YieldHandling yieldHandling,
    4801           1 :                                                    unsigned errorNumber)
    4802             : {
    4803             :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Lc));
    4804           1 :     uint32_t openedPos = pos().begin;
    4805           1 : 
    4806             :     ParseContext::Statement stmt(pc, StatementKind::Block);
    4807       42456 :     ParseContext::Scope scope(this);
    4808       28304 :     if (!scope.init(pc))
    4809       14152 :         return null();
    4810             : 
    4811             :     Node list = statementList(yieldHandling);
    4812       14152 :     if (!list)
    4813           0 :         return null();
    4814             : 
    4815             :     MUST_MATCH_TOKEN_MOD_WITH_REPORT(TokenKind::Rc, TokenStream::Operand,
    4816           0 :                                      reportMissingClosing(errorNumber, JSMSG_CURLY_OPENED,
    4817             :                                                           openedPos));
    4818             : 
    4819             :     return finishLexicalScope(scope, list);
    4820           0 : }
    4821             : 
    4822             : template <class ParseHandler, typename CharT>
    4823             : typename ParseHandler::Node
    4824             : GeneralParser<ParseHandler, CharT>::expressionAfterForInOrOf(ParseNodeKind forHeadKind,
    4825           0 :                                                              YieldHandling yieldHandling)
    4826             : {
    4827             :     MOZ_ASSERT(forHeadKind == ParseNodeKind::ForIn || forHeadKind == ParseNodeKind::ForOf);
    4828           0 :     Node pn = forHeadKind == ParseNodeKind::ForOf
    4829             :            ? assignExpr(InAllowed, yieldHandling, TripledotProhibited)
    4830        1256 :            : expr(InAllowed, yieldHandling, TripledotProhibited);
    4831        1256 :     return pn;
    4832           0 : }
    4833             : 
    4834             : template <class ParseHandler, typename CharT>
    4835             : typename ParseHandler::Node
    4836             : GeneralParser<ParseHandler, CharT>::declarationPattern(DeclarationKind declKind, TokenKind tt,
    4837           0 :                                                        bool initialDeclaration,
    4838             :                                                        YieldHandling yieldHandling,
    4839             :                                                        ParseNodeKind* forHeadKind,
    4840             :                                                        Node* forInOrOfExpression)
    4841             : {
    4842             :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Lb) ||
    4843           0 :                anyChars.isCurrentTokenType(TokenKind::Lc));
    4844             : 
    4845             :     Node pattern = destructuringDeclaration(declKind, yieldHandling, tt);
    4846         718 :     if (!pattern)
    4847         718 :         return null();
    4848             : 
    4849             :     if (initialDeclaration && forHeadKind) {
    4850         718 :         bool isForIn, isForOf;
    4851             :         if (!matchInOrOf(&isForIn, &isForOf))
    4852         194 :             return null();
    4853         194 : 
    4854             :         if (isForIn) {
    4855           0 :             *forHeadKind = ParseNodeKind::ForIn;
    4856           0 :         } else if (isForOf) {
    4857         194 :             *forHeadKind = ParseNodeKind::ForOf;
    4858           0 : 
    4859             :             // Annex B.3.5 has different early errors for vars in for-of loops.
    4860             :             if (declKind == DeclarationKind::Var)
    4861             :                 declKind = DeclarationKind::ForOfVar;
    4862             :         } else {
    4863             :             *forHeadKind = ParseNodeKind::ForHead;
    4864           0 :         }
    4865             : 
    4866             :         if (*forHeadKind != ParseNodeKind::ForHead) {
    4867           0 :             *forInOrOfExpression = expressionAfterForInOrOf(*forHeadKind, yieldHandling);
    4868           0 :             if (!*forInOrOfExpression)
    4869           0 :                 return null();
    4870             : 
    4871             :             return pattern;
    4872         194 :         }
    4873             :     }
    4874             : 
    4875             :     MUST_MATCH_TOKEN_MOD(TokenKind::Assign, TokenStream::Operand, JSMSG_BAD_DESTRUCT_DECL);
    4876           0 : 
    4877             :     Node init = assignExpr(forHeadKind ? InProhibited : InAllowed,
    4878         524 :                            yieldHandling, TripledotProhibited);
    4879           0 :     if (!init)
    4880           0 :         return null();
    4881             : 
    4882             :     return handler.newAssignment(ParseNodeKind::Assign, pattern, init);
    4883         524 : }
    4884             : 
    4885             : template <class ParseHandler, typename CharT>
    4886             : bool
    4887             : GeneralParser<ParseHandler, CharT>::initializerInNameDeclaration(Node binding,
    4888           0 :                                                                  DeclarationKind declKind,
    4889             :                                                                  bool initialDeclaration,
    4890             :                                                                  YieldHandling yieldHandling,
    4891             :                                                                  ParseNodeKind* forHeadKind,
    4892             :                                                                  Node* forInOrOfExpression)
    4893             : {
    4894             :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Assign));
    4895           0 : 
    4896             :     uint32_t initializerOffset;
    4897             :     if (!tokenStream.peekOffset(&initializerOffset, TokenStream::Operand))
    4898       29144 :         return false;
    4899             : 
    4900             :     Node initializer = assignExpr(forHeadKind ? InProhibited : InAllowed,
    4901       14572 :                                   yieldHandling, TripledotProhibited);
    4902       14572 :     if (!initializer)
    4903       14572 :         return false;
    4904             : 
    4905             :     if (forHeadKind && initialDeclaration) {
    4906       14572 :         bool isForIn, isForOf;
    4907             :         if (!matchInOrOf(&isForIn, &isForOf))
    4908         323 :             return false;
    4909           0 : 
    4910             :         // An initialized declaration can't appear in a for-of:
    4911             :         //
    4912             :         //   for (var/let/const x = ... of ...); // BAD
    4913             :         if (isForOf) {
    4914           0 :             errorAt(initializerOffset, JSMSG_OF_AFTER_FOR_LOOP_DECL);
    4915           0 :             return false;
    4916           0 :         }
    4917             : 
    4918             :         if (isForIn) {
    4919         323 :             // Lexical declarations in for-in loops can't be initialized:
    4920             :             //
    4921             :             //   for (let/const x = ... in ...); // BAD
    4922             :             if (DeclarationKindIsLexical(declKind)) {
    4923           0 :                 errorAt(initializerOffset, JSMSG_IN_AFTER_LEXICAL_FOR_DECL);
    4924           0 :                 return false;
    4925           0 :             }
    4926             : 
    4927             :             // This leaves only initialized for-in |var| declarations.  ES6
    4928             :             // forbids these; later ES un-forbids in non-strict mode code.
    4929             :             *forHeadKind = ParseNodeKind::ForIn;
    4930           0 :             if (!strictModeErrorAt(initializerOffset, JSMSG_INVALID_FOR_IN_DECL_WITH_INIT))
    4931           0 :                 return false;
    4932             : 
    4933             :             *forInOrOfExpression = expressionAfterForInOrOf(ParseNodeKind::ForIn, yieldHandling);
    4934           0 :             if (!*forInOrOfExpression)
    4935           0 :                 return false;
    4936             :         } else {
    4937             :             *forHeadKind = ParseNodeKind::ForHead;
    4938         323 :         }
    4939             :     }
    4940             : 
    4941             :     return handler.finishInitializerAssignment(binding, initializer);
    4942           0 : }
    4943             : 
    4944             : template <class ParseHandler, typename CharT>
    4945             : typename ParseHandler::Node
    4946             : GeneralParser<ParseHandler, CharT>::declarationName(DeclarationKind declKind, TokenKind tt,
    4947           0 :                                                     bool initialDeclaration,
    4948             :                                                     YieldHandling yieldHandling,
    4949             :                                                     ParseNodeKind* forHeadKind,
    4950             :                                                     Node* forInOrOfExpression)
    4951             : {
    4952             :     // Anything other than possible identifier is an error.
    4953             :     if (!TokenKindIsPossibleIdentifier(tt)) {
    4954           0 :         error(JSMSG_NO_VARIABLE_NAME);
    4955           0 :         return null();
    4956           0 :     }
    4957             : 
    4958             :     RootedPropertyName name(context, bindingIdentifier(yieldHandling));
    4959           0 :     if (!name)
    4960       16391 :         return null();
    4961             : 
    4962             :     Node binding = newName(name);
    4963       16391 :     if (!binding)
    4964       16391 :         return null();
    4965             : 
    4966             :     TokenPos namePos = pos();
    4967           0 : 
    4968             :     // The '=' context after a variable name in a declaration is an opportunity
    4969             :     // for ASI, and thus for the next token to start an ExpressionStatement:
    4970             :     //
    4971             :     //  var foo   // VariableDeclaration
    4972             :     //  /bar/g;   // ExpressionStatement
    4973             :     //
    4974             :     // Therefore get the token here as Operand.
    4975             :     bool matched;
    4976             :     if (!tokenStream.matchToken(&matched, TokenKind::Assign, TokenStream::Operand))
    4977       16391 :         return null();
    4978             : 
    4979             :     if (matched) {
    4980       16391 :         if (!initializerInNameDeclaration(binding, declKind, initialDeclaration,
    4981       14572 :                                           yieldHandling, forHeadKind, forInOrOfExpression))
    4982             :         {
    4983             :             return null();
    4984             :         }
    4985             :     } else {
    4986             :         if (initialDeclaration && forHeadKind) {
    4987        1819 :             bool isForIn, isForOf;
    4988             :             if (!matchInOrOf(&isForIn, &isForOf))
    4989           0 :                 return null();
    4990           0 : 
    4991             :             if (isForIn) {
    4992           0 :                 *forHeadKind = ParseNodeKind::ForIn;
    4993           0 :             } else if (isForOf) {
    4994         920 :                 *forHeadKind = ParseNodeKind::ForOf;
    4995         920 : 
    4996             :                 // Annex B.3.5 has different early errors for vars in for-of loops.
    4997             :                 if (declKind == DeclarationKind::Var)
    4998         920 :                     declKind = DeclarationKind::ForOfVar;
    4999           0 :             } else {
    5000             :                 *forHeadKind = ParseNodeKind::ForHead;
    5001           0 :             }
    5002             :         }
    5003             : 
    5004             :         if (forHeadKind && *forHeadKind != ParseNodeKind::ForHead) {
    5005           0 :             *forInOrOfExpression = expressionAfterForInOrOf(*forHeadKind, yieldHandling);
    5006           0 :             if (!*forInOrOfExpression)
    5007           0 :                 return null();
    5008             :         } else {
    5009             :             // Normal const declarations, and const declarations in for(;;)
    5010             :             // heads, must be initialized.
    5011             :             if (declKind == DeclarationKind::Const) {
    5012         761 :                 errorAt(namePos.begin, JSMSG_BAD_CONST_DECL);
    5013           0 :                 return null();
    5014           0 :             }
    5015             :         }
    5016             :     }
    5017             : 
    5018             :     // Note the declared name after knowing whether or not we are in a for-of
    5019             :     // loop, due to special early error semantics in Annex B.3.5.
    5020             :     if (!noteDeclaredName(name, declKind, namePos))
    5021       16391 :         return null();
    5022             : 
    5023             :     return binding;
    5024           0 : }
    5025             : 
    5026             : template <class ParseHandler, typename CharT>
    5027             : typename ParseHandler::Node
    5028             : GeneralParser<ParseHandler, CharT>::declarationList(YieldHandling yieldHandling,
    5029       16988 :                                                     ParseNodeKind kind,
    5030             :                                                     ParseNodeKind* forHeadKind /* = nullptr */,
    5031             :                                                     Node* forInOrOfExpression /* = nullptr */)
    5032             : {
    5033             :     MOZ_ASSERT(kind == ParseNodeKind::Var ||
    5034       16988 :                kind == ParseNodeKind::Let ||
    5035             :                kind == ParseNodeKind::Const);
    5036             : 
    5037             :     DeclarationKind declKind;
    5038             :     switch (kind) {
    5039       16988 :       case ParseNodeKind::Var:
    5040             :         declKind = DeclarationKind::Var;
    5041             :         break;
    5042             :       case ParseNodeKind::Const:
    5043             :         declKind = DeclarationKind::Const;
    5044        2689 :         break;
    5045        2689 :       case ParseNodeKind::Let:
    5046             :         declKind = DeclarationKind::Let;
    5047       10731 :         break;
    5048       10731 :       default:
    5049             :         MOZ_CRASH("Unknown declaration kind");
    5050           0 :     }
    5051             : 
    5052             :     Node decl = handler.newDeclarationList(kind, pos());
    5053       33976 :     if (!decl)
    5054       16988 :         return null();
    5055             : 
    5056             :     bool moreDeclarations;
    5057             :     bool initialDeclaration = true;
    5058             :     do {
    5059           0 :         MOZ_ASSERT_IF(!initialDeclaration && forHeadKind,
    5060           0 :                       *forHeadKind == ParseNodeKind::ForHead);
    5061             : 
    5062             :         TokenKind tt;
    5063             :         if (!tokenStream.getToken(&tt))
    5064       17109 :             return null();
    5065           0 : 
    5066             :         Node binding = (tt == TokenKind::Lb || tt == TokenKind::Lc)
    5067       17109 :                        ? declarationPattern(declKind, tt, initialDeclaration, yieldHandling,
    5068       33500 :                                             forHeadKind, forInOrOfExpression)
    5069             :                        : declarationName(declKind, tt, initialDeclaration, yieldHandling,
    5070       16391 :                                          forHeadKind, forInOrOfExpression);
    5071           0 :         if (!binding)
    5072           0 :             return null();
    5073             : 
    5074             :         handler.addList(decl, binding);
    5075       34218 : 
    5076             :         // If we have a for-in/of loop, the above call matches the entirety
    5077             :         // of the loop head (up to the closing parenthesis).
    5078             :         if (forHeadKind && *forHeadKind != ParseNodeKind::ForHead)
    5079           0 :             break;
    5080             : 
    5081             :         initialDeclaration = false;
    5082           0 : 
    5083             :         if (!tokenStream.matchToken(&moreDeclarations, TokenKind::Comma, TokenStream::Operand))
    5084           0 :             return null();
    5085             :     } while (moreDeclarations);
    5086             : 
    5087             :     return decl;
    5088             : }
    5089             : 
    5090             : template <class ParseHandler, typename CharT>
    5091             : typename ParseHandler::Node
    5092             : GeneralParser<ParseHandler, CharT>::lexicalDeclaration(YieldHandling yieldHandling,
    5093       11998 :                                                        DeclarationKind kind)
    5094             : {
    5095             :     MOZ_ASSERT(kind == DeclarationKind::Const || kind == DeclarationKind::Let);
    5096           0 : 
    5097             :     /*
    5098             :      * Parse body-level lets without a new block object. ES6 specs
    5099             :      * that an execution environment's initial lexical environment
    5100             :      * is the VariableEnvironment, i.e., body-level lets are in
    5101             :      * the same environment record as vars.
    5102             :      *
    5103             :      * However, they cannot be parsed exactly as vars, as ES6
    5104             :      * requires that uninitialized lets throw ReferenceError on use.
    5105             :      *
    5106             :      * See 8.1.1.1.6 and the note in 13.2.1.
    5107             :      */
    5108             :     Node decl = declarationList(yieldHandling,
    5109       11998 :                                 kind == DeclarationKind::Const
    5110             :                                 ? ParseNodeKind::Const
    5111             :                                 : ParseNodeKind::Let);
    5112       11998 :     if (!decl || !matchOrInsertSemicolon())
    5113       11998 :         return null();
    5114             : 
    5115             :     return decl;
    5116       11998 : }
    5117             : 
    5118             : template <typename CharT>
    5119             : bool
    5120             : Parser<FullParseHandler, CharT>::namedImportsOrNamespaceImport(TokenKind tt, Node importSpecSet)
    5121           0 : {
    5122             :     if (tt == TokenKind::Lc) {
    5123           0 :         while (true) {
    5124             :             // Handle the forms |import {} from 'a'| and
    5125             :             // |import { ..., } from 'a'| (where ... is non empty), by
    5126             :             // escaping the loop early if the next token is }.
    5127             :             if (!tokenStream.getToken(&tt))
    5128           0 :                 return false;
    5129           0 : 
    5130             :             if (tt == TokenKind::Rc)
    5131           0 :                 break;
    5132             : 
    5133             :             if (!TokenKindIsPossibleIdentifierName(tt)) {
    5134           0 :                 error(JSMSG_NO_IMPORT_NAME);
    5135           0 :                 return false;
    5136           0 :             }
    5137             : 
    5138             :             Rooted<PropertyName*> importName(context, anyChars.currentName());
    5139           0 :             TokenPos importNamePos = pos();
    5140           0 : 
    5141             :             bool matched;
    5142             :             if (!tokenStream.matchToken(&matched, TokenKind::As))
    5143           0 :                 return null();
    5144           0 : 
    5145             :             if (matched) {
    5146           0 :                 TokenKind afterAs;
    5147             :                 if (!tokenStream.getToken(&afterAs))
    5148           0 :                     return false;
    5149           0 : 
    5150             :                 if (!TokenKindIsPossibleIdentifierName(afterAs)) {
    5151           0 :                     error(JSMSG_NO_BINDING_NAME);
    5152           0 :                     return false;
    5153           0 :                 }
    5154             :             } else {
    5155             :                 // Keywords cannot be bound to themselves, so an import name
    5156             :                 // that is a keyword is a syntax error if it is not followed
    5157             :                 // by the keyword 'as'.
    5158             :                 // See the ImportSpecifier production in ES6 section 15.2.2.
    5159             :                 if (IsKeyword(importName)) {
    5160           0 :                     error(JSMSG_AS_AFTER_RESERVED_WORD, ReservedWordToCharZ(importName));
    5161           0 :                     return false;
    5162           0 :                 }
    5163             :             }
    5164             : 
    5165             :             RootedPropertyName bindingAtom(context, importedBinding());
    5166           0 :             if (!bindingAtom)
    5167           0 :                 return false;
    5168           0 : 
    5169             :             Node bindingName = newName(bindingAtom);
    5170           0 :             if (!bindingName)
    5171           0 :                 return false;
    5172             :             if (!noteDeclaredName(bindingAtom, DeclarationKind::Import, pos()))
    5173           0 :                 return false;
    5174             : 
    5175             :             Node importNameNode = newName(importName, importNamePos);
    5176           0 :             if (!importNameNode)
    5177           0 :                 return false;
    5178             : 
    5179             :             Node importSpec = handler.newImportSpec(importNameNode, bindingName);
    5180           0 :             if (!importSpec)
    5181           0 :                 return false;
    5182             : 
    5183             :             handler.addList(importSpecSet, importSpec);
    5184           0 : 
    5185             :             TokenKind next;
    5186             :             if (!tokenStream.getToken(&next))
    5187           0 :                 return false;
    5188             : 
    5189             :             if (next == TokenKind::Rc)
    5190           0 :                 break;
    5191             : 
    5192             :             if (next != TokenKind::Comma) {
    5193           0 :                 error(JSMSG_RC_AFTER_IMPORT_SPEC_LIST);
    5194           0 :                 return false;
    5195           0 :             }
    5196             :         }
    5197             :     } else {
    5198             :         MOZ_ASSERT(tt == TokenKind::Mul);
    5199           0 : 
    5200             :         MUST_MATCH_TOKEN(TokenKind::As, JSMSG_AS_AFTER_IMPORT_STAR);
    5201           0 : 
    5202             :         MUST_MATCH_TOKEN_FUNC(TokenKindIsPossibleIdentifierName, JSMSG_NO_BINDING_NAME);
    5203           0 : 
    5204             :         Node importName = newName(context->names().star);
    5205           0 :         if (!importName)
    5206           0 :             return false;
    5207             : 
    5208             :         // Namespace imports are are not indirect bindings but lexical
    5209             :         // definitions that hold a module namespace object. They are treated
    5210             :         // as const variables which are initialized during the
    5211             :         // ModuleInstantiate step.
    5212             :         RootedPropertyName bindingName(context, importedBinding());
    5213           0 :         if (!bindingName)
    5214           0 :             return false;
    5215           0 :         Node bindingNameNode = newName(bindingName);
    5216           0 :         if (!bindingNameNode)
    5217           0 :             return false;
    5218             :         if (!noteDeclaredName(bindingName, DeclarationKind::Const, pos()))
    5219           0 :             return false;
    5220             : 
    5221             :         // The namespace import name is currently required to live on the
    5222             :         // environment.
    5223             :         pc->varScope().lookupDeclaredName(bindingName)->value()->setClosedOver();
    5224           0 : 
    5225             :         Node importSpec = handler.newImportSpec(importName, bindingNameNode);
    5226           0 :         if (!importSpec)
    5227           0 :             return false;
    5228             : 
    5229             :         handler.addList(importSpecSet, importSpec);
    5230           0 :     }
    5231             : 
    5232             :     return true;
    5233             : }
    5234             : 
    5235             : template<typename CharT>
    5236             : ParseNode*
    5237             : Parser<FullParseHandler, CharT>::importDeclaration()
    5238           0 : {
    5239             :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Import));
    5240           0 : 
    5241             :     if (!pc->atModuleLevel()) {
    5242           0 :         error(JSMSG_IMPORT_DECL_AT_TOP_LEVEL);
    5243           0 :         return null();
    5244           0 :     }
    5245             : 
    5246             :     uint32_t begin = pos().begin;
    5247           0 :     TokenKind tt;
    5248             :     if (!tokenStream.getToken(&tt))
    5249           0 :         return null();
    5250             : 
    5251             :     Node importSpecSet = handler.newList(ParseNodeKind::ImportSpecList, pos());
    5252           0 :     if (!importSpecSet)
    5253           0 :         return null();
    5254             : 
    5255             :     if (tt == TokenKind::String) {
    5256           0 :         // Handle the form |import 'a'| by leaving the list empty. This is
    5257             :         // equivalent to |import {} from 'a'|.
    5258             :         importSpecSet->pn_pos.end = importSpecSet->pn_pos.begin;
    5259           0 :     } else {
    5260             :         if (tt == TokenKind::Lc || tt == TokenKind::Mul) {
    5261           0 :             if (!namedImportsOrNamespaceImport(tt, importSpecSet))
    5262           0 :                 return null();
    5263             :         } else if (TokenKindIsPossibleIdentifierName(tt)) {
    5264           0 :             // Handle the form |import a from 'b'|, by adding a single import
    5265             :             // specifier to the list, with 'default' as the import name and
    5266             :             // 'a' as the binding name. This is equivalent to
    5267             :             // |import { default as a } from 'b'|.
    5268             :             Node importName = newName(context->names().default_);
    5269           0 :             if (!importName)
    5270           0 :                 return null();
    5271           0 : 
    5272             :             RootedPropertyName bindingAtom(context, importedBinding());
    5273           0 :             if (!bindingAtom)
    5274           0 :                 return null();
    5275           0 : 
    5276             :             Node bindingName = newName(bindingAtom);
    5277           0 :             if (!bindingName)
    5278           0 :                 return null();
    5279             : 
    5280             :             if (!noteDeclaredName(bindingAtom, DeclarationKind::Import, pos()))
    5281           0 :                 return null();
    5282             : 
    5283             :             Node importSpec = handler.newImportSpec(importName, bindingName);
    5284           0 :             if (!importSpec)
    5285           0 :                 return null();
    5286             : 
    5287             :             handler.addList(importSpecSet, importSpec);
    5288           0 : 
    5289             :             if (!tokenStream.peekToken(&tt))
    5290           0 :                 return null();
    5291             : 
    5292             :             if (tt == TokenKind::Comma) {
    5293           0 :                 tokenStream.consumeKnownToken(tt);
    5294           0 :                 if (!tokenStream.getToken(&tt))
    5295           0 :                     return null();
    5296             : 
    5297             :                 if (tt != TokenKind::Lc && tt != TokenKind::Mul) {
    5298           0 :                     error(JSMSG_NAMED_IMPORTS_OR_NAMESPACE_IMPORT);
    5299           0 :                     return null();
    5300           0 :                 }
    5301             : 
    5302             :                 if (!namedImportsOrNamespaceImport(tt, importSpecSet))
    5303           0 :                     return null();
    5304             :             }
    5305             :         } else {
    5306             :             error(JSMSG_DECLARATION_AFTER_IMPORT);
    5307           0 :             return null();
    5308           0 :         }
    5309             : 
    5310             :         MUST_MATCH_TOKEN(TokenKind::From, JSMSG_FROM_AFTER_IMPORT_CLAUSE);
    5311           0 : 
    5312             :         MUST_MATCH_TOKEN(TokenKind::String, JSMSG_MODULE_SPEC_AFTER_FROM);
    5313           0 :     }
    5314             : 
    5315             :     Node moduleSpec = stringLiteral();
    5316           0 :     if (!moduleSpec)
    5317           0 :         return null();
    5318             : 
    5319             :     if (!matchOrInsertSemicolon())
    5320           0 :         return null();
    5321             : 
    5322             :     ParseNode* node =
    5323             :         handler.newImportDeclaration(importSpecSet, moduleSpec, TokenPos(begin, pos().end));
    5324           0 :     if (!node || !pc->sc()->asModuleContext()->builder.processImport(node))
    5325           0 :         return null();
    5326             : 
    5327             :     return node;
    5328           0 : }
    5329             : 
    5330             : template<typename CharT>
    5331             : inline SyntaxParseHandler::Node
    5332             : Parser<SyntaxParseHandler, CharT>::importDeclaration()
    5333           0 : {
    5334             :     MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
    5335           0 :     return SyntaxParseHandler::NodeFailure;
    5336           0 : }
    5337             : 
    5338             : template <class ParseHandler, typename CharT>
    5339             : inline typename ParseHandler::Node
    5340             : GeneralParser<ParseHandler, CharT>::importDeclaration()
    5341           0 : {
    5342             :     return asFinalParser()->importDeclaration();
    5343           0 : }
    5344             : 
    5345             : template <class ParseHandler, typename CharT>
    5346             : inline typename ParseHandler::Node
    5347             : GeneralParser<ParseHandler, CharT>::importDeclarationOrImportMeta(YieldHandling yieldHandling)
    5348           0 : {
    5349             :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Import));
    5350           0 : 
    5351             :     TokenKind tt;
    5352             :     if (!tokenStream.peekToken(&tt))
    5353           0 :         return null();
    5354             : 
    5355             :     if (tt == TokenKind::Dot)
    5356           0 :         return expressionStatement(yieldHandling);
    5357           0 : 
    5358             :     return importDeclaration();
    5359           0 : }
    5360             : 
    5361             : template<typename CharT>
    5362             : bool
    5363             : Parser<FullParseHandler, CharT>::checkExportedName(JSAtom* exportName)
    5364           0 : {
    5365             :     if (!pc->sc()->asModuleContext()->builder.hasExportedName(exportName))
    5366           0 :         return true;
    5367             : 
    5368             :     JSAutoByteString str;
    5369           0 :     if (!AtomToPrintableString(context, exportName, &str))
    5370           0 :         return false;
    5371             : 
    5372             :     error(JSMSG_DUPLICATE_EXPORT_NAME, str.ptr());
    5373           0 :     return false;
    5374           0 : }
    5375             : 
    5376             : template<typename CharT>
    5377             : inline bool
    5378             : Parser<SyntaxParseHandler, CharT>::checkExportedName(JSAtom* exportName)
    5379           0 : {
    5380             :     MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
    5381           0 :     return false;
    5382           0 : }
    5383             : 
    5384             : template<class ParseHandler, typename CharT>
    5385             : inline bool
    5386             : GeneralParser<ParseHandler, CharT>::checkExportedName(JSAtom* exportName)
    5387           0 : {
    5388             :     return asFinalParser()->checkExportedName(exportName);
    5389           0 : }
    5390             : 
    5391             : template<typename CharT>
    5392             : bool
    5393             : Parser<FullParseHandler, CharT>::checkExportedNamesForArrayBinding(ParseNode* pn)
    5394           0 : {
    5395             :     MOZ_ASSERT(pn->isKind(ParseNodeKind::Array));
    5396           0 :     MOZ_ASSERT(pn->isArity(PN_LIST));
    5397           0 : 
    5398             :     for (ParseNode* node = pn->pn_head; node; node = node->pn_next) {
    5399           0 :         if (node->isKind(ParseNodeKind::Elision))
    5400           0 :             continue;
    5401             : 
    5402             :         ParseNode* binding;
    5403             :         if (node->isKind(ParseNodeKind::Spread))
    5404           0 :             binding = node->pn_kid;
    5405           0 :         else if (node->isKind(ParseNodeKind::Assign))
    5406           0 :             binding = node->pn_left;
    5407           0 :         else
    5408             :             binding = node;
    5409             : 
    5410             :         if (!checkExportedNamesForDeclaration(binding))
    5411           0 :             return false;
    5412             :     }
    5413             : 
    5414             :     return true;
    5415             : }
    5416             : 
    5417             : template<typename CharT>
    5418             : inline bool
    5419             : Parser<SyntaxParseHandler, CharT>::checkExportedNamesForArrayBinding(Node node)
    5420           0 : {
    5421             :     MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
    5422           0 :     return false;
    5423           0 : }
    5424             : 
    5425             : template<class ParseHandler, typename CharT>
    5426             : inline bool
    5427             : GeneralParser<ParseHandler, CharT>::checkExportedNamesForArrayBinding(Node node)
    5428           0 : {
    5429             :     return asFinalParser()->checkExportedNamesForArrayBinding(node);
    5430           0 : }
    5431             : 
    5432             : template<typename CharT>
    5433             : bool
    5434             : Parser<FullParseHandler, CharT>::checkExportedNamesForObjectBinding(ParseNode* pn)
    5435           0 : {
    5436             :     MOZ_ASSERT(pn->isKind(ParseNodeKind::Object));
    5437           0 :     MOZ_ASSERT(pn->isArity(PN_LIST));
    5438           0 : 
    5439             :     for (ParseNode* node = pn->pn_head; node; node = node->pn_next) {
    5440           0 :         MOZ_ASSERT(node->isKind(ParseNodeKind::MutateProto) ||
    5441           0 :                    node->isKind(ParseNodeKind::Colon) ||
    5442             :                    node->isKind(ParseNodeKind::Shorthand) ||
    5443             :                    node->isKind(ParseNodeKind::Spread));
    5444             : 
    5445           0 :         ParseNode* target;
    5446             :         if (node->isKind(ParseNodeKind::Spread)) {
    5447           0 :             target = node->pn_kid;
    5448             :         } else {
    5449           0 :             if (node->isKind(ParseNodeKind::MutateProto))
    5450           0 :                 target = node->pn_kid;
    5451             :             else
    5452           0 :                 target = node->pn_right;
    5453             : 
    5454             :             if (target->isKind(ParseNodeKind::Assign))
    5455             :                 target = target->pn_left;
    5456             :         }
    5457             : 
    5458             :         if (!checkExportedNamesForDeclaration(target))
    5459             :             return false;
    5460             :     }
    5461           0 : 
    5462             :     return true;
    5463           0 : }
    5464           0 : 
    5465             : template<typename CharT>
    5466             : inline bool
    5467             : Parser<SyntaxParseHandler, CharT>::checkExportedNamesForObjectBinding(Node node)
    5468             : {
    5469           0 :     MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
    5470             :     return false;
    5471           0 : }
    5472             : 
    5473             : template<class ParseHandler, typename CharT>
    5474             : inline bool
    5475             : GeneralParser<ParseHandler, CharT>::checkExportedNamesForObjectBinding(Node node)
    5476           0 : {
    5477             :     return asFinalParser()->checkExportedNamesForObjectBinding(node);
    5478           0 : }
    5479           0 : 
    5480             : template<typename CharT>
    5481           0 : bool
    5482           0 : Parser<FullParseHandler, CharT>::checkExportedNamesForDeclaration(ParseNode* node)
    5483             : {
    5484             :     if (node->isKind(ParseNodeKind::Name)) {
    5485           0 :         if (!checkExportedName(node->pn_atom))
    5486           0 :             return false;
    5487             :     } else if (node->isKind(ParseNodeKind::Array)) {
    5488             :         if (!checkExportedNamesForArrayBinding(node))
    5489             :             return false;
    5490             :     } else {
    5491             :         MOZ_ASSERT(node->isKind(ParseNodeKind::Object));
    5492             :         if (!checkExportedNamesForObjectBinding(node))
    5493             :             return false;
    5494             :     }
    5495           0 : 
    5496             :     return true;
    5497           0 : }
    5498           0 : 
    5499             : template<typename CharT>
    5500             : inline bool
    5501             : Parser<SyntaxParseHandler, CharT>::checkExportedNamesForDeclaration(Node node)
    5502             : {
    5503           0 :     MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
    5504             :     return false;
    5505           0 : }
    5506             : 
    5507             : template<class ParseHandler, typename CharT>
    5508             : inline bool
    5509             : GeneralParser<ParseHandler, CharT>::checkExportedNamesForDeclaration(Node node)
    5510           0 : {
    5511             :     return asFinalParser()->checkExportedNamesForDeclaration(node);
    5512           0 : }
    5513           0 : 
    5514           0 : template<typename CharT>
    5515           0 : bool
    5516             : Parser<FullParseHandler, CharT>::checkExportedNamesForDeclarationList(ParseNode* node)
    5517           0 : {
    5518             :     MOZ_ASSERT(node->isArity(PN_LIST));
    5519           0 :     for (ParseNode* binding = node->pn_head; binding; binding = binding->pn_next) {
    5520             :         if (binding->isKind(ParseNodeKind::Assign))
    5521             :             binding = binding->pn_left;
    5522             :         else
    5523             :             MOZ_ASSERT(binding->isKind(ParseNodeKind::Name));
    5524             : 
    5525             :         if (!checkExportedNamesForDeclaration(binding))
    5526             :             return false;
    5527             :     }
    5528           0 : 
    5529             :     return true;
    5530           0 : }
    5531           0 : 
    5532             : template<typename CharT>
    5533             : inline bool
    5534             : Parser<SyntaxParseHandler, CharT>::checkExportedNamesForDeclarationList(Node node)
    5535             : {
    5536           0 :     MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
    5537             :     return false;
    5538           0 : }
    5539             : 
    5540             : template<class ParseHandler, typename CharT>
    5541             : inline bool
    5542             : GeneralParser<ParseHandler, CharT>::checkExportedNamesForDeclarationList(Node node)
    5543           0 : {
    5544             :     return asFinalParser()->checkExportedNamesForDeclarationList(node);
    5545           0 : }
    5546             : 
    5547             : template<typename CharT>
    5548             : inline bool
    5549             : Parser<FullParseHandler, CharT>::checkExportedNameForClause(ParseNode* node)
    5550           0 : {
    5551             :     return checkExportedName(node->pn_atom);
    5552           0 : }
    5553           0 : 
    5554             : template<typename CharT>
    5555             : inline bool
    5556             : Parser<SyntaxParseHandler, CharT>::checkExportedNameForClause(Node node)
    5557             : {
    5558           0 :     MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
    5559             :     return false;
    5560           0 : }
    5561             : 
    5562             : template<class ParseHandler, typename CharT>
    5563             : inline bool
    5564             : GeneralParser<ParseHandler, CharT>::checkExportedNameForClause(Node node)
    5565           0 : {
    5566             :     return asFinalParser()->checkExportedNameForClause(node);
    5567           0 : }
    5568             : 
    5569             : template<typename CharT>
    5570             : bool
    5571             : Parser<FullParseHandler, CharT>::checkExportedNameForFunction(ParseNode* node)
    5572           0 : {
    5573             :     return checkExportedName(node->pn_funbox->function()->explicitName());
    5574           0 : }
    5575           0 : 
    5576             : template<typename CharT>
    5577             : inline bool
    5578             : Parser<SyntaxParseHandler, CharT>::checkExportedNameForFunction(Node node)
    5579             : {
    5580           0 :     MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
    5581             :     return false;
    5582           0 : }
    5583             : 
    5584             : template<class ParseHandler, typename CharT>
    5585             : inline bool
    5586             : GeneralParser<ParseHandler, CharT>::checkExportedNameForFunction(Node node)
    5587           0 : {
    5588             :     return asFinalParser()->checkExportedNameForFunction(node);
    5589           0 : }
    5590           0 : 
    5591           0 : template<typename CharT>
    5592             : bool
    5593             : Parser<FullParseHandler, CharT>::checkExportedNameForClass(ParseNode* node)
    5594             : {
    5595             :     const ClassNode& cls = node->as<ClassNode>();
    5596           0 :     MOZ_ASSERT(cls.names());
    5597             :     return checkExportedName(cls.names()->innerBinding()->pn_atom);
    5598           0 : }
    5599           0 : 
    5600             : template<typename CharT>
    5601             : inline bool
    5602             : Parser<SyntaxParseHandler, CharT>::checkExportedNameForClass(Node node)
    5603             : {
    5604           0 :     MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
    5605             :     return false;
    5606           0 : }
    5607             : 
    5608             : template<class ParseHandler, typename CharT>
    5609             : inline bool
    5610             : GeneralParser<ParseHandler, CharT>::checkExportedNameForClass(Node node)
    5611           0 : {
    5612             :     return asFinalParser()->checkExportedNameForClass(node);
    5613           0 : }
    5614             : 
    5615             : template<>
    5616             : inline bool
    5617             : PerHandlerParser<FullParseHandler>::processExport(ParseNode* node)
    5618             : {
    5619             :     return pc->sc()->asModuleContext()->builder.processExport(node);
    5620             : }
    5621             : 
    5622             : template<>
    5623             : inline bool
    5624             : PerHandlerParser<SyntaxParseHandler>::processExport(Node node)
    5625             : {
    5626           0 :     MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
    5627             :     return false;
    5628           0 : }
    5629             : 
    5630             : template<>
    5631             : inline bool
    5632             : PerHandlerParser<FullParseHandler>::processExportFrom(ParseNode* node)
    5633             : {
    5634             :     return pc->sc()->asModuleContext()->builder.processExportFrom(node);
    5635             : }
    5636             : 
    5637             : template<>
    5638             : inline bool
    5639             : PerHandlerParser<SyntaxParseHandler>::processExportFrom(Node node)
    5640             : {
    5641           0 :     MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
    5642             :     return false;
    5643           0 : }
    5644             : 
    5645             : template <class ParseHandler, typename CharT>
    5646           0 : typename ParseHandler::Node
    5647             : GeneralParser<ParseHandler, CharT>::exportFrom(uint32_t begin, Node specList)
    5648           0 : {
    5649             :     if (!abortIfSyntaxParser())
    5650             :         return null();
    5651           0 : 
    5652             :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::From));
    5653           0 : 
    5654           0 :     if (!abortIfSyntaxParser())
    5655             :         return null();
    5656             : 
    5657           0 :     MUST_MATCH_TOKEN(TokenKind::String, JSMSG_MODULE_SPEC_AFTER_FROM);
    5658             : 
    5659             :     Node moduleSpec = stringLiteral();
    5660           0 :     if (!moduleSpec)
    5661           0 :         return null();
    5662             : 
    5663             :     if (!matchOrInsertSemicolon())
    5664           0 :         return null();
    5665             : 
    5666             :     Node node = handler.newExportFromDeclaration(begin, specList, moduleSpec);
    5667           0 :     if (!node)
    5668             :         return null();
    5669             : 
    5670             :     if (!processExportFrom(node))
    5671             :         return null();
    5672           0 : 
    5673             :     return node;
    5674           0 : }
    5675             : 
    5676             : template <class ParseHandler, typename CharT>
    5677           0 : typename ParseHandler::Node
    5678             : GeneralParser<ParseHandler, CharT>::exportBatch(uint32_t begin)
    5679           0 : {
    5680           0 :     if (!abortIfSyntaxParser())
    5681             :         return null();
    5682             : 
    5683             :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Mul));
    5684             : 
    5685           0 :     Node kid = handler.newList(ParseNodeKind::ExportSpecList, pos());
    5686           0 :     if (!kid)
    5687             :         return null();
    5688             : 
    5689           0 :     // Handle the form |export *| by adding a special export batch
    5690             :     // specifier to the list.
    5691           0 :     Node exportSpec = handler.newExportBatchSpec(pos());
    5692             :     if (!exportSpec)
    5693           0 :         return null();
    5694             : 
    5695             :     handler.addList(kid, exportSpec);
    5696             : 
    5697             :     MUST_MATCH_TOKEN(TokenKind::From, JSMSG_FROM_AFTER_EXPORT_STAR);
    5698           0 : 
    5699             :     return exportFrom(begin, kid);
    5700             : }
    5701           0 : 
    5702           0 : template<typename CharT>
    5703           0 : bool
    5704             : Parser<FullParseHandler, CharT>::checkLocalExportNames(ParseNode* node)
    5705           0 : {
    5706           0 :     // ES 2017 draft 15.2.3.1.
    5707           0 :     for (ParseNode* next = node->pn_head; next; next = next->pn_next) {
    5708             :         ParseNode* name = next->pn_left;
    5709             :         MOZ_ASSERT(name->isKind(ParseNodeKind::Name));
    5710             : 
    5711             :         RootedPropertyName ident(context, name->pn_atom->asPropertyName());
    5712             :         if (!checkLocalExportName(ident, name->pn_pos.begin))
    5713             :             return false;
    5714             :     }
    5715           0 : 
    5716             :     return true;
    5717           0 : }
    5718           0 : 
    5719             : template<typename CharT>
    5720             : bool
    5721             : Parser<SyntaxParseHandler, CharT>::checkLocalExportNames(Node node)
    5722             : {
    5723           0 :     MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
    5724             :     return false;
    5725           0 : }
    5726             : 
    5727             : template<class ParseHandler, typename CharT>
    5728             : inline bool
    5729             : GeneralParser<ParseHandler, CharT>::checkLocalExportNames(Node node)
    5730           0 : {
    5731             :     return asFinalParser()->checkLocalExportNames(node);
    5732           0 : }
    5733             : 
    5734             : template <class ParseHandler, typename CharT>
    5735           0 : typename ParseHandler::Node
    5736             : GeneralParser<ParseHandler, CharT>::exportClause(uint32_t begin)
    5737           0 : {
    5738           0 :     if (!abortIfSyntaxParser())
    5739             :         return null();
    5740             : 
    5741             :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Lc));
    5742           0 : 
    5743             :     Node kid = handler.newList(ParseNodeKind::ExportSpecList, pos());
    5744             :     if (!kid)
    5745           0 :         return null();
    5746           0 : 
    5747             :     TokenKind tt;
    5748           0 :     while (true) {
    5749             :         // Handle the forms |export {}| and |export { ..., }| (where ... is non
    5750             :         // empty), by escaping the loop early if the next token is }.
    5751           0 :         if (!tokenStream.getToken(&tt))
    5752           0 :             return null();
    5753           0 : 
    5754             :         if (tt == TokenKind::Rc)
    5755             :             break;
    5756           0 : 
    5757           0 :         if (!TokenKindIsPossibleIdentifierName(tt)) {
    5758             :             error(JSMSG_NO_BINDING_NAME);
    5759             :             return null();
    5760             :         }
    5761           0 : 
    5762             :         Node bindingName = newName(anyChars.currentName());
    5763           0 :         if (!bindingName)
    5764           0 :             return null();
    5765             : 
    5766           0 :         bool foundAs;
    5767           0 :         if (!tokenStream.matchToken(&foundAs, TokenKind::As))
    5768             :             return null();
    5769             :         if (foundAs)
    5770           0 :             MUST_MATCH_TOKEN_FUNC(TokenKindIsPossibleIdentifierName, JSMSG_NO_EXPORT_NAME);
    5771             : 
    5772             :         Node exportName = newName(anyChars.currentName());
    5773           0 :         if (!exportName)
    5774           0 :             return null();
    5775             : 
    5776             :         if (!checkExportedNameForClause(exportName))
    5777           0 :             return null();
    5778             : 
    5779             :         Node exportSpec = handler.newExportSpec(bindingName, exportName);
    5780           0 :         if (!exportSpec)
    5781             :             return null();
    5782             : 
    5783           0 :         handler.addList(kid, exportSpec);
    5784             : 
    5785             :         TokenKind next;
    5786           0 :         if (!tokenStream.getToken(&next))
    5787           0 :             return null();
    5788           0 : 
    5789             :         if (next == TokenKind::Rc)
    5790             :             break;
    5791             : 
    5792             :         if (next != TokenKind::Comma) {
    5793             :             error(JSMSG_RC_AFTER_EXPORT_SPEC_LIST);
    5794             :             return null();
    5795             :         }
    5796             :     }
    5797             : 
    5798             :     // Careful!  If |from| follows, even on a new line, it must start a
    5799             :     // FromClause:
    5800             :     //
    5801             :     //   export { x }
    5802             :     //   from "foo"; // a single ExportDeclaration
    5803             :     //
    5804             :     // But if it doesn't, we might have an ASI opportunity in Operand context:
    5805             :     //
    5806           0 :     //   export { x }   // ExportDeclaration, terminated by ASI
    5807             :     //   fro\u006D      // ExpressionStatement, the name "from"
    5808             :     //
    5809           0 :     // In that case let matchOrInsertSemicolon sort out ASI or any necessary
    5810           0 :     // error.
    5811             :     bool matched;
    5812           0 :     if (!tokenStream.matchToken(&matched, TokenKind::From, TokenStream::Operand))
    5813             :         return null();
    5814             : 
    5815           0 :     if (matched)
    5816             :         return exportFrom(begin, kid);
    5817             : 
    5818           0 :     if (!matchOrInsertSemicolon())
    5819           0 :         return null();
    5820             : 
    5821             :     if (!checkLocalExportNames(kid))
    5822           0 :         return null();
    5823             : 
    5824             :     Node node = handler.newExportDeclaration(kid, TokenPos(begin, pos().end));
    5825           0 :     if (!node)
    5826             :         return null();
    5827             : 
    5828             :     if (!processExport(node))
    5829             :         return null();
    5830           0 : 
    5831             :     return node;
    5832           0 : }
    5833             : 
    5834             : template <class ParseHandler, typename CharT>
    5835           0 : typename ParseHandler::Node
    5836             : GeneralParser<ParseHandler, CharT>::exportVariableStatement(uint32_t begin)
    5837           0 : {
    5838           0 :     if (!abortIfSyntaxParser())
    5839             :         return null();
    5840           0 : 
    5841             :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Var));
    5842           0 : 
    5843             :     Node kid = declarationList(YieldIsName, ParseNodeKind::Var);
    5844             :     if (!kid)
    5845           0 :         return null();
    5846           0 :     if (!matchOrInsertSemicolon())
    5847             :         return null();
    5848             :     if (!checkExportedNamesForDeclarationList(kid))
    5849           0 :         return null();
    5850             : 
    5851             :     Node node = handler.newExportDeclaration(kid, TokenPos(begin, pos().end));
    5852           0 :     if (!node)
    5853             :         return null();
    5854             : 
    5855             :     if (!processExport(node))
    5856             :         return null();
    5857           0 : 
    5858             :     return node;
    5859             : }
    5860             : 
    5861           0 : template <class ParseHandler, typename CharT>
    5862             : typename ParseHandler::Node
    5863             : GeneralParser<ParseHandler, CharT>::exportFunctionDeclaration(uint32_t begin,
    5864           0 :                                                               uint32_t toStringStart,
    5865             :                                                               FunctionAsyncKind asyncKind /* = SyncFunction */)
    5866           0 : {
    5867           0 :     if (!abortIfSyntaxParser())
    5868             :         return null();
    5869             : 
    5870           0 :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Function));
    5871             : 
    5872             :     Node kid = functionStmt(toStringStart, YieldIsName, NameRequired, asyncKind);
    5873           0 :     if (!kid)
    5874           0 :         return null();
    5875             : 
    5876             :     if (!checkExportedNameForFunction(kid))
    5877           0 :         return null();
    5878             : 
    5879             :     Node node = handler.newExportDeclaration(kid, TokenPos(begin, pos().end));
    5880           0 :     if (!node)
    5881             :         return null();
    5882             : 
    5883             :     if (!processExport(node))
    5884             :         return null();
    5885           0 : 
    5886             :     return node;
    5887           0 : }
    5888             : 
    5889             : template <class ParseHandler, typename CharT>
    5890           0 : typename ParseHandler::Node
    5891             : GeneralParser<ParseHandler, CharT>::exportClassDeclaration(uint32_t begin)
    5892           0 : {
    5893           0 :     if (!abortIfSyntaxParser())
    5894             :         return null();
    5895             : 
    5896           0 :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Class));
    5897             : 
    5898             :     Node kid = classDefinition(YieldIsName, ClassStatement, NameRequired);
    5899           0 :     if (!kid)
    5900           0 :         return null();
    5901             : 
    5902             :     if (!checkExportedNameForClass(kid))
    5903           0 :         return null();
    5904             : 
    5905             :     Node node = handler.newExportDeclaration(kid, TokenPos(begin, pos().end));
    5906           0 :     if (!node)
    5907             :         return null();
    5908             : 
    5909             :     if (!processExport(node))
    5910             :         return null();
    5911           0 : 
    5912             :     return node;
    5913           0 : }
    5914             : 
    5915             : template <class ParseHandler, typename CharT>
    5916           0 : typename ParseHandler::Node
    5917           0 : GeneralParser<ParseHandler, CharT>::exportLexicalDeclaration(uint32_t begin, DeclarationKind kind)
    5918           0 : {
    5919             :     if (!abortIfSyntaxParser())
    5920           0 :         return null();
    5921           0 : 
    5922             :     MOZ_ASSERT(kind == DeclarationKind::Const || kind == DeclarationKind::Let);
    5923           0 :     MOZ_ASSERT_IF(kind == DeclarationKind::Const, anyChars.isCurrentTokenType(TokenKind::Const));
    5924             :     MOZ_ASSERT_IF(kind == DeclarationKind::Let, anyChars.isCurrentTokenType(TokenKind::Let));
    5925             : 
    5926           0 :     Node kid = lexicalDeclaration(YieldIsName, kind);
    5927           0 :     if (!kid)
    5928             :         return null();
    5929             :     if (!checkExportedNamesForDeclarationList(kid))
    5930           0 :         return null();
    5931             : 
    5932             :     Node node = handler.newExportDeclaration(kid, TokenPos(begin, pos().end));
    5933           0 :     if (!node)
    5934             :         return null();
    5935             : 
    5936             :     if (!processExport(node))
    5937             :         return null();
    5938           0 : 
    5939             :     return node;
    5940             : }
    5941             : 
    5942           0 : template <class ParseHandler, typename CharT>
    5943             : typename ParseHandler::Node
    5944             : GeneralParser<ParseHandler, CharT>::exportDefaultFunctionDeclaration(uint32_t begin,
    5945           0 :                                                                      uint32_t toStringStart,
    5946             :                                                                      FunctionAsyncKind asyncKind /* = SyncFunction */)
    5947           0 : {
    5948           0 :     if (!abortIfSyntaxParser())
    5949             :         return null();
    5950             : 
    5951           0 :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Function));
    5952           0 : 
    5953             :     Node kid = functionStmt(toStringStart, YieldIsName, AllowDefaultName, asyncKind);
    5954             :     if (!kid)
    5955           0 :         return null();
    5956             : 
    5957             :     Node node = handler.newExportDefaultDeclaration(kid, null(), TokenPos(begin, pos().end));
    5958           0 :     if (!node)
    5959             :         return null();
    5960             : 
    5961             :     if (!processExport(node))
    5962             :         return null();
    5963           0 : 
    5964             :     return node;
    5965           0 : }
    5966             : 
    5967             : template <class ParseHandler, typename CharT>
    5968           0 : typename ParseHandler::Node
    5969             : GeneralParser<ParseHandler, CharT>::exportDefaultClassDeclaration(uint32_t begin)
    5970           0 : {
    5971           0 :     if (!abortIfSyntaxParser())
    5972             :         return null();
    5973             : 
    5974           0 :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Class));
    5975           0 : 
    5976             :     Node kid = classDefinition(YieldIsName, ClassStatement, AllowDefaultName);
    5977             :     if (!kid)
    5978           0 :         return null();
    5979             : 
    5980             :     Node node = handler.newExportDefaultDeclaration(kid, null(), TokenPos(begin, pos().end));
    5981           0 :     if (!node)
    5982             :         return null();
    5983             : 
    5984             :     if (!processExport(node))
    5985             :         return null();
    5986           0 : 
    5987             :     return node;
    5988           0 : }
    5989             : 
    5990             : template <class ParseHandler, typename CharT>
    5991           0 : typename ParseHandler::Node
    5992           0 : GeneralParser<ParseHandler, CharT>::exportDefaultAssignExpr(uint32_t begin)
    5993           0 : {
    5994             :     if (!abortIfSyntaxParser())
    5995           0 :         return null();
    5996             : 
    5997             :     HandlePropertyName name = context->names().default_;
    5998           0 :     Node nameNode = newName(name);
    5999           0 :     if (!nameNode)
    6000             :         return null();
    6001             :     if (!noteDeclaredName(name, DeclarationKind::Const, pos()))
    6002           0 :         return null();
    6003             : 
    6004             :     Node kid = assignExpr(InAllowed, YieldIsName, TripledotProhibited);
    6005           0 :     if (!kid)
    6006           0 :         return null();
    6007             : 
    6008             :     if (!matchOrInsertSemicolon())
    6009           0 :         return null();
    6010             : 
    6011             :     Node node = handler.newExportDefaultDeclaration(kid, nameNode, TokenPos(begin, pos().end));
    6012           0 :     if (!node)
    6013             :         return null();
    6014             : 
    6015             :     if (!processExport(node))
    6016             :         return null();
    6017           0 : 
    6018             :     return node;
    6019           0 : }
    6020             : 
    6021             : template <class ParseHandler, typename CharT>
    6022           0 : typename ParseHandler::Node
    6023             : GeneralParser<ParseHandler, CharT>::exportDefault(uint32_t begin)
    6024             : {
    6025           0 :     if (!abortIfSyntaxParser())
    6026             :         return null();
    6027             : 
    6028           0 :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Default));
    6029             : 
    6030             :     TokenKind tt;
    6031           0 :     if (!tokenStream.getToken(&tt, TokenStream::Operand))
    6032             :         return null();
    6033           0 : 
    6034             :     if (!checkExportedName(context->names().default_))
    6035             :         return null();
    6036           0 : 
    6037           0 :     switch (tt) {
    6038             :       case TokenKind::Function:
    6039             :         return exportDefaultFunctionDeclaration(begin, pos().begin);
    6040           0 : 
    6041           0 :       case TokenKind::Async: {
    6042           0 :         TokenKind nextSameLine = TokenKind::Eof;
    6043             :         if (!tokenStream.peekTokenSameLine(&nextSameLine))
    6044           0 :             return null();
    6045             : 
    6046             :         if (nextSameLine == TokenKind::Function) {
    6047           0 :             uint32_t toStringStart = pos().begin;
    6048           0 :             tokenStream.consumeKnownToken(TokenKind::Function);
    6049             :             return exportDefaultFunctionDeclaration(begin, toStringStart,
    6050             :                                                     FunctionAsyncKind::AsyncFunction);
    6051             :         }
    6052           0 : 
    6053             :         anyChars.ungetToken();
    6054             :         return exportDefaultAssignExpr(begin);
    6055           0 :       }
    6056           0 : 
    6057             :       case TokenKind::Class:
    6058             :         return exportDefaultClassDeclaration(begin);
    6059             : 
    6060             :       default:
    6061             :         anyChars.ungetToken();
    6062           0 :         return exportDefaultAssignExpr(begin);
    6063             :     }
    6064           0 : }
    6065             : 
    6066             : template <class ParseHandler, typename CharT>
    6067           0 : typename ParseHandler::Node
    6068             : GeneralParser<ParseHandler, CharT>::exportDeclaration()
    6069           0 : {
    6070           0 :     if (!abortIfSyntaxParser())
    6071           0 :         return null();
    6072             : 
    6073             :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Export));
    6074           0 : 
    6075             :     if (!pc->atModuleLevel()) {
    6076             :         error(JSMSG_EXPORT_DECL_AT_TOP_LEVEL);
    6077           0 :         return null();
    6078             :     }
    6079           0 : 
    6080             :     uint32_t begin = pos().begin;
    6081           0 : 
    6082             :     TokenKind tt;
    6083             :     if (!tokenStream.getToken(&tt))
    6084           0 :         return null();
    6085             :     switch (tt) {
    6086             :       case TokenKind::Mul:
    6087           0 :         return exportBatch(begin);
    6088             : 
    6089             :       case TokenKind::Lc:
    6090           0 :         return exportClause(begin);
    6091             : 
    6092             :       case TokenKind::Var:
    6093           0 :         return exportVariableStatement(begin);
    6094           0 : 
    6095             :       case TokenKind::Function:
    6096             :         return exportFunctionDeclaration(begin, pos().begin);
    6097           0 : 
    6098           0 :       case TokenKind::Async: {
    6099           0 :         TokenKind nextSameLine = TokenKind::Eof;
    6100             :         if (!tokenStream.peekTokenSameLine(&nextSameLine))
    6101           0 :             return null();
    6102             : 
    6103             :         if (nextSameLine == TokenKind::Function) {
    6104           0 :             uint32_t toStringStart = pos().begin;
    6105           0 :             tokenStream.consumeKnownToken(TokenKind::Function);
    6106             :             return exportFunctionDeclaration(begin, toStringStart,
    6107             :                                              FunctionAsyncKind::AsyncFunction);
    6108             :         }
    6109           0 : 
    6110             :         error(JSMSG_DECLARATION_AFTER_EXPORT);
    6111             :         return null();
    6112           0 :       }
    6113             : 
    6114             :       case TokenKind::Class:
    6115           0 :         return exportClassDeclaration(begin);
    6116             : 
    6117             :       case TokenKind::Const:
    6118           0 :         return exportLexicalDeclaration(begin, DeclarationKind::Const);
    6119             : 
    6120             :       case TokenKind::Let:
    6121           0 :         return exportLexicalDeclaration(begin, DeclarationKind::Let);
    6122           0 : 
    6123             :       case TokenKind::Default:
    6124             :         return exportDefault(begin);
    6125             : 
    6126             :       default:
    6127             :         error(JSMSG_DECLARATION_AFTER_EXPORT);
    6128       32192 :         return null();
    6129             :     }
    6130             : }
    6131       32192 : 
    6132             : template <class ParseHandler, typename CharT>
    6133           0 : typename ParseHandler::Node
    6134           0 : GeneralParser<ParseHandler, CharT>::expressionStatement(YieldHandling yieldHandling,
    6135             :                                                         InvokedPrediction invoked)
    6136       32192 : {
    6137             :     anyChars.ungetToken();
    6138       64384 :     Node pnexpr = expr(InAllowed, yieldHandling, TripledotProhibited,
    6139             :                        /* possibleError = */ nullptr, invoked);
    6140             :     if (!pnexpr)
    6141             :         return null();
    6142             :     if (!matchOrInsertSemicolon())
    6143           0 :         return null();
    6144             :     return handler.newExprStatement(pnexpr, pos().end);
    6145             : }
    6146           0 : 
    6147             : template <class ParseHandler, typename CharT>
    6148             : typename ParseHandler::Node
    6149             : GeneralParser<ParseHandler, CharT>::consequentOrAlternative(YieldHandling yieldHandling)
    6150             : {
    6151             :     TokenKind next;
    6152             :     if (!tokenStream.peekToken(&next, TokenStream::Operand))
    6153             :         return null();
    6154             : 
    6155           0 :     // Annex B.3.4 says that unbraced FunctionDeclarations under if/else in
    6156           0 :     // non-strict code act as if they were braced: |if (x) function f() {}|
    6157             :     // parses as |if (x) { function f() {} }|.
    6158             :     //
    6159             :     // Careful!  FunctionDeclaration doesn't include generators or async
    6160           0 :     // functions.
    6161           0 :     if (next == TokenKind::Function) {
    6162           0 :         tokenStream.consumeKnownToken(next, TokenStream::Operand);
    6163             : 
    6164             :         // Parser::statement would handle this, but as this function handles
    6165             :         // every other error case, it seems best to handle this.
    6166           0 :         if (pc->sc()->strict()) {
    6167             :             error(JSMSG_FORBIDDEN_AS_STATEMENT, "function declarations");
    6168             :             return null();
    6169           0 :         }
    6170           0 : 
    6171           0 :         TokenKind maybeStar;
    6172             :         if (!tokenStream.peekToken(&maybeStar))
    6173             :             return null();
    6174           0 : 
    6175           0 :         if (maybeStar == TokenKind::Mul) {
    6176           0 :             error(JSMSG_FORBIDDEN_AS_STATEMENT, "generator declarations");
    6177             :             return null();
    6178             :         }
    6179           0 : 
    6180           0 :         ParseContext::Statement stmt(pc, StatementKind::Block);
    6181           0 :         ParseContext::Scope scope(this);
    6182             :         if (!scope.init(pc))
    6183             :             return null();
    6184           0 : 
    6185           0 :         TokenPos funcPos = pos();
    6186             :         Node fun = functionStmt(pos().begin, yieldHandling, NameRequired);
    6187             :         if (!fun)
    6188           0 :             return null();
    6189           0 : 
    6190             :         Node block = handler.newStatementList(funcPos);
    6191             :         if (!block)
    6192           0 :             return null();
    6193             : 
    6194             :         handler.addStatementToList(block, fun);
    6195             :         return finishLexicalScope(scope, block);
    6196             :     }
    6197           0 : 
    6198             :     return statement(yieldHandling);
    6199       51464 : }
    6200           0 : 
    6201             : template <class ParseHandler, typename CharT>
    6202             : typename ParseHandler::Node
    6203       25732 : GeneralParser<ParseHandler, CharT>::ifStatement(YieldHandling yieldHandling)
    6204             : {
    6205         689 :     Vector<Node, 4> condList(context), thenList(context);
    6206       27110 :     Vector<uint32_t, 4> posList(context);
    6207             :     Node elseBranch;
    6208             : 
    6209           0 :     ParseContext::Statement stmt(pc, StatementKind::If);
    6210       13555 : 
    6211           0 :     while (true) {
    6212             :         uint32_t begin = pos().begin;
    6213             : 
    6214       13555 :         /* An IF node has three kids: condition, then, and optional else. */
    6215             :         Node cond = condition(InAllowed, yieldHandling);
    6216       13555 :         if (!cond)
    6217           0 :             return null();
    6218             : 
    6219             :         TokenKind tt;
    6220             :         if (!tokenStream.peekToken(&tt, TokenStream::Operand))
    6221           0 :             return null();
    6222           0 :         if (tt == TokenKind::Semi) {
    6223             :             if (!extraWarning(JSMSG_EMPTY_CONSEQUENT))
    6224             :                 return null();
    6225       13555 :         }
    6226             : 
    6227             :         Node thenBranch = consequentOrAlternative(yieldHandling);
    6228             :         if (!thenBranch)
    6229           0 :             return null();
    6230             : 
    6231       13555 :         if (!condList.append(cond) || !thenList.append(thenBranch) || !posList.append(begin))
    6232        2066 :             return null();
    6233             : 
    6234           0 :         bool matched;
    6235         689 :         if (!tokenStream.matchToken(&matched, TokenKind::Else, TokenStream::Operand))
    6236        1377 :             return null();
    6237           0 :         if (matched) {
    6238             :             if (!tokenStream.matchToken(&matched, TokenKind::If, TokenStream::Operand))
    6239             :                 return null();
    6240             :             if (matched)
    6241             :                 continue;
    6242       12866 :             elseBranch = consequentOrAlternative(yieldHandling);
    6243             :             if (!elseBranch)
    6244             :                 return null();
    6245       26421 :         } else {
    6246           0 :             elseBranch = null();
    6247           0 :         }
    6248             :         break;
    6249             :     }
    6250             : 
    6251             :     for (int i = condList.length() - 1; i >= 0; i--) {
    6252             :         elseBranch = handler.newIfStatement(posList[i], condList[i], thenList[i], elseBranch);
    6253             :         if (!elseBranch)
    6254             :             return null();
    6255             :     }
    6256         290 : 
    6257             :     return elseBranch;
    6258           0 : }
    6259           0 : 
    6260         290 : template <class ParseHandler, typename CharT>
    6261         290 : typename ParseHandler::Node
    6262             : GeneralParser<ParseHandler, CharT>::doWhileStatement(YieldHandling yieldHandling)
    6263         290 : {
    6264         290 :     uint32_t begin = pos().begin;
    6265         290 :     ParseContext::Statement stmt(pc, StatementKind::DoLoop);
    6266             :     Node body = statement(yieldHandling);
    6267             :     if (!body)
    6268             :         return null();
    6269             :     MUST_MATCH_TOKEN_MOD(TokenKind::While, TokenStream::Operand, JSMSG_WHILE_AFTER_DO);
    6270             :     Node cond = condition(InAllowed, yieldHandling);
    6271             :     if (!cond)
    6272             :         return null();
    6273             : 
    6274             :     // The semicolon after do-while is even more optional than most
    6275           0 :     // semicolons in JS.  Web compat required this by 2004:
    6276             :     //   http://bugzilla.mozilla.org/show_bug.cgi?id=238945
    6277           0 :     // ES3 and ES5 disagreed, but ES6 conforms to Web reality:
    6278             :     //   https://bugs.ecmascript.org/show_bug.cgi?id=157
    6279             :     // To parse |do {} while (true) false| correctly, use Operand.
    6280             :     bool ignored;
    6281             :     if (!tokenStream.matchToken(&ignored, TokenKind::Semi, TokenStream::Operand))
    6282         268 :         return null();
    6283             :     return handler.newDoWhileStatement(body, cond, TokenPos(begin, pos().end));
    6284         536 : }
    6285         804 : 
    6286         268 : template <class ParseHandler, typename CharT>
    6287           0 : typename ParseHandler::Node
    6288             : GeneralParser<ParseHandler, CharT>::whileStatement(YieldHandling yieldHandling)
    6289           0 : {
    6290         268 :     uint32_t begin = pos().begin;
    6291             :     ParseContext::Statement stmt(pc, StatementKind::WhileLoop);
    6292         536 :     Node cond = condition(InAllowed, yieldHandling);
    6293             :     if (!cond)
    6294             :         return null();
    6295             :     Node body = statement(yieldHandling);
    6296             :     if (!body)
    6297           0 :         return null();
    6298             :     return handler.newWhileStatement(begin, cond, body);
    6299             : }
    6300        1587 : 
    6301             : template <class ParseHandler, typename CharT>
    6302             : bool
    6303        1587 : GeneralParser<ParseHandler, CharT>::matchInOrOf(bool* isForInp, bool* isForOfp)
    6304           0 : {
    6305        1587 :     TokenKind tt;
    6306         331 :     if (!tokenStream.getToken(&tt, TokenStream::Operand))
    6307             :         return false;
    6308        1587 : 
    6309             :     *isForInp = tt == TokenKind::In;
    6310             :     *isForOfp = tt == TokenKind::Of;
    6311             :     if (!*isForInp && !*isForOfp)
    6312             :         anyChars.ungetToken();
    6313             : 
    6314        1610 :     MOZ_ASSERT_IF(*isForInp || *isForOfp, *isForInp != *isForOfp);
    6315             :     return true;
    6316             : }
    6317             : 
    6318             : template <class ParseHandler, typename CharT>
    6319        3220 : bool
    6320             : GeneralParser<ParseHandler, CharT>::forHeadStart(YieldHandling yieldHandling,
    6321             :                                                  ParseNodeKind* forHeadKind, Node* forInitialPart,
    6322        1610 :                                                  Maybe<ParseContext::Scope>& forLoopLexicalScope,
    6323             :                                                  Node* forInOrOfExpression)
    6324             : {
    6325             :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Lp));
    6326             : 
    6327        1610 :     TokenKind tt;
    6328          23 :     if (!tokenStream.peekToken(&tt, TokenStream::Operand))
    6329          23 :         return null();
    6330          23 : 
    6331             :     // Super-duper easy case: |for (;| is a C-style for-loop with no init
    6332             :     // component.
    6333             :     if (tt == TokenKind::Semi) {
    6334             :         *forInitialPart = null();
    6335             :         *forHeadKind = ParseNodeKind::ForHead;
    6336        1587 :         return true;
    6337         153 :     }
    6338             : 
    6339             :     // Parsing after |for (var| is also relatively simple (from this method's
    6340           0 :     // point of view).  No block-related work complicates matters, so delegate
    6341             :     // to Parser::declaration.
    6342           0 :     if (tt == TokenKind::Var) {
    6343             :         tokenStream.consumeKnownToken(tt, TokenStream::Operand);
    6344             : 
    6345             :         // Pass null for block object because |var| declarations don't use one.
    6346             :         *forInitialPart = declarationList(yieldHandling, ParseNodeKind::Var, forHeadKind,
    6347             :                                           forInOrOfExpression);
    6348             :         return *forInitialPart != null();
    6349             :     }
    6350        1434 : 
    6351        1434 :     // Otherwise we have a lexical declaration or an expression.
    6352           0 : 
    6353          96 :     // For-in loop backwards compatibility requires that |let| starting a
    6354           0 :     // for-loop that's not a (new to ES6) for-of loop, in non-strict mode code,
    6355        1338 :     // parse as an identifier.  (|let| in for-of is always a declaration.)
    6356             :     bool parsingLexicalDeclaration = false;
    6357             :     bool letIsIdentifier = false;
    6358             :     if (tt == TokenKind::Const) {
    6359             :         parsingLexicalDeclaration = true;
    6360        1326 :         tokenStream.consumeKnownToken(tt, TokenStream::Operand);
    6361             :     } else if (tt == TokenKind::Let) {
    6362             :         // We could have a {For,Lexical}Declaration, or we could have a
    6363           0 :         // LeftHandSideExpression with lookahead restrictions so it's not
    6364           0 :         // ambiguous with the former.  Check for a continuation of the former
    6365             :         // to decide which we have.
    6366           0 :         tokenStream.consumeKnownToken(TokenKind::Let, TokenStream::Operand);
    6367           0 : 
    6368           0 :         TokenKind next;
    6369           0 :         if (!tokenStream.peekToken(&next))
    6370             :             return false;
    6371             : 
    6372             :         parsingLexicalDeclaration = nextTokenContinuesLetDeclaration(next);
    6373        1434 :         if (!parsingLexicalDeclaration) {
    6374        1422 :             anyChars.ungetToken();
    6375           0 :             letIsIdentifier = true;
    6376             :         }
    6377             :     }
    6378             : 
    6379             :     if (parsingLexicalDeclaration) {
    6380             :         forLoopLexicalScope.emplace(this);
    6381           0 :         if (!forLoopLexicalScope->init(pc))
    6382             :             return null();
    6383        1422 : 
    6384        1422 :         // Push a temporary ForLoopLexicalHead Statement that allows for
    6385             :         // lexical declarations, as they are usually allowed only in braced
    6386             :         // statements.
    6387             :         ParseContext::Statement forHeadStmt(pc, StatementKind::ForLoopLexicalHead);
    6388        1422 : 
    6389             :         *forInitialPart = declarationList(yieldHandling,
    6390             :                                           tt == TokenKind::Const
    6391             :                                           ? ParseNodeKind::Const
    6392          24 :                                           : ParseNodeKind::Let,
    6393             :                                           forHeadKind, forInOrOfExpression);
    6394             :         return *forInitialPart != null();
    6395             :     }
    6396             : 
    6397             :     uint32_t exprOffset;
    6398          12 :     if (!tokenStream.peekOffset(&exprOffset, TokenStream::Operand))
    6399          12 :         return false;
    6400           0 : 
    6401             :     // Finally, handle for-loops that start with expressions.  Pass
    6402             :     // |InProhibited| so that |in| isn't parsed in a RelationalExpression as a
    6403             :     // binary operator.  |in| makes it a for-in loop, *not* an |in| expression.
    6404           0 :     PossibleError possibleError(*this);
    6405             :     *forInitialPart = expr(InProhibited, yieldHandling, TripledotProhibited, &possibleError);
    6406             :     if (!*forInitialPart)
    6407             :         return false;
    6408             : 
    6409          12 :     bool isForIn, isForOf;
    6410           0 :     if (!matchInOrOf(&isForIn, &isForOf))
    6411             :         return false;
    6412             : 
    6413           8 :     // If we don't encounter 'in'/'of', we have a for(;;) loop.  We've handled
    6414           8 :     // the init expression; the caller handles the rest.
    6415             :     if (!isForIn && !isForOf) {
    6416             :         if (!possibleError.checkForExpressionError())
    6417           4 :             return false;
    6418             : 
    6419             :         *forHeadKind = ParseNodeKind::ForHead;
    6420             :         return true;
    6421             :     }
    6422             : 
    6423             :     MOZ_ASSERT(isForIn != isForOf);
    6424             : 
    6425             :     // In a for-of loop, 'let' that starts the loop head is a |let| keyword,
    6426             :     // per the [lookahead ≠ let] restriction on the LeftHandSideExpression
    6427             :     // variant of such loops.  Expressions that start with |let| can't be used
    6428             :     // here.
    6429           0 :     //
    6430           0 :     //   var let = {};
    6431           0 :     //   for (let.prop of [1]) // BAD
    6432             :     //     break;
    6433             :     //
    6434           4 :     // See ES6 13.7.
    6435             :     if (isForOf && letIsIdentifier) {
    6436             :         errorAt(exprOffset, JSMSG_LET_STARTING_FOROF_LHS);
    6437           4 :         return false;
    6438           0 :     }
    6439             : 
    6440           8 :     *forHeadKind = isForIn ? ParseNodeKind::ForIn : ParseNodeKind::ForOf;
    6441           0 : 
    6442             :     // Verify the left-hand side expression doesn't have a forbidden form.
    6443           0 :     if (handler.isUnparenthesizedDestructuringPattern(*forInitialPart)) {
    6444             :         if (!possibleError.checkForDestructuringErrorOrWarning())
    6445             :             return false;
    6446             :     } else if (handler.isName(*forInitialPart)) {
    6447           4 :         if (const char* chars = nameIsArgumentsOrEval(*forInitialPart)) {
    6448           0 :             // |chars| is "arguments" or "eval" here.
    6449             :             if (!strictModeErrorAt(exprOffset, JSMSG_BAD_STRICT_ASSIGN, chars))
    6450           0 :                 return false;
    6451           0 :         }
    6452             : 
    6453             :         handler.adjustGetToSet(*forInitialPart);
    6454           0 :     } else if (handler.isPropertyAccess(*forInitialPart)) {
    6455           0 :         // Permitted: no additional testing/fixup needed.
    6456             :     } else if (handler.isFunctionCall(*forInitialPart)) {
    6457             :         if (!strictModeErrorAt(exprOffset, JSMSG_BAD_FOR_LEFTSIDE))
    6458           4 :             return false;
    6459             :     } else {
    6460             :         errorAt(exprOffset, JSMSG_BAD_FOR_LEFTSIDE);
    6461             :         return false;
    6462             :     }
    6463           0 : 
    6464           4 :     if (!possibleError.checkForExpressionError())
    6465             :         return false;
    6466             : 
    6467             :     // Finally, parse the iterated expression, making the for-loop's closing
    6468             :     // ')' the next token.
    6469        1610 :     *forInOrOfExpression = expressionAfterForInOrOf(*forHeadKind, yieldHandling);
    6470             :     return *forInOrOfExpression != null();
    6471        3220 : }
    6472             : 
    6473        3220 : template <class ParseHandler, typename CharT>
    6474             : typename ParseHandler::Node
    6475           0 : GeneralParser<ParseHandler, CharT>::forStatement(YieldHandling yieldHandling)
    6476             : {
    6477        1610 :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::For));
    6478        1610 : 
    6479             :     uint32_t begin = pos().begin;
    6480        3220 : 
    6481             :     ParseContext::Statement stmt(pc, StatementKind::ForLoop);
    6482         210 : 
    6483           0 :     IteratorKind iterKind = IteratorKind::Sync;
    6484             :     unsigned iflags = 0;
    6485           0 : 
    6486           0 :     if (pc->isAsync()) {
    6487           0 :         bool matched;
    6488             :         if (!tokenStream.matchToken(&matched, TokenKind::Await))
    6489             :             return null();
    6490             : 
    6491        1610 :         if (matched) {
    6492             :             iflags |= JSITER_FORAWAITOF;
    6493             :             iterKind = IteratorKind::Async;
    6494             :         }
    6495             :     }
    6496             : 
    6497             :     MUST_MATCH_TOKEN_MOD_WITH_REPORT(TokenKind::Lp, TokenStream::None,
    6498             :                                      error((token == TokenKind::Await && !pc->isAsync())
    6499             :                                            ? JSMSG_FOR_AWAIT_OUTSIDE_ASYNC
    6500             :                                            : JSMSG_PAREN_AFTER_FOR));
    6501             : 
    6502             :     // ParseNodeKind::ForHead, ParseNodeKind::ForIn, or
    6503             :     // ParseNodeKind::ForOf depending on the loop type.
    6504             :     ParseNodeKind headKind;
    6505             : 
    6506             :     // |x| in either |for (x; ...; ...)| or |for (x in/of ...)|.
    6507             :     Node startNode;
    6508             : 
    6509             :     // The next two variables are used to implement `for (let/const ...)`.
    6510             :     //
    6511             :     // We generate an implicit block, wrapping the whole loop, to store loop
    6512             :     // variables declared this way. Note that if the loop uses `for (var...)`
    6513        1610 :     // instead, those variables go on some existing enclosing scope, so no
    6514             :     // implicit block scope is created.
    6515             :     //
    6516             :     // Both variables remain null/none if the loop is any other form.
    6517             : 
    6518             :     // The static block scope for the implicit block scope.
    6519             :     Maybe<ParseContext::Scope> forLoopLexicalScope;
    6520             : 
    6521             :     // The expression being iterated over, for for-in/of loops only.  Unused
    6522             :     // for for(;;) loops.
    6523             :     Node iteratedExpr;
    6524             : 
    6525             :     // Parse the entirety of the loop-head for a for-in/of loop (so the next
    6526             :     // token is the closing ')'):
    6527             :     //
    6528             :     //   for (... in/of ...) ...
    6529             :     //                     ^next token
    6530             :     //
    6531             :     // ...OR, parse up to the first ';' in a C-style for-loop:
    6532        1610 :     //
    6533             :     //   for (...; ...; ...) ...
    6534             :     //           ^next token
    6535        1610 :     //
    6536             :     // In either case the subsequent token can be consistently accessed using
    6537             :     // TokenStream::None semantics.
    6538             :     if (!forHeadStart(yieldHandling, &headKind, &startNode, forLoopLexicalScope, &iteratedExpr))
    6539        1610 :         return null();
    6540           0 : 
    6541           0 :     MOZ_ASSERT(headKind == ParseNodeKind::ForIn ||
    6542             :                headKind == ParseNodeKind::ForOf ||
    6543             :                headKind == ParseNodeKind::ForHead);
    6544             : 
    6545        1610 :     if (iterKind == IteratorKind::Async && headKind != ParseNodeKind::ForOf) {
    6546         354 :         errorAt(begin, JSMSG_FOR_AWAIT_NOT_OF);
    6547             :         return null();
    6548             :     }
    6549             : 
    6550         354 :     Node forHead;
    6551             :     if (headKind == ParseNodeKind::ForHead) {
    6552             :         Node init = startNode;
    6553           0 : 
    6554             :         // Look for an operand: |for (;| means we might have already examined
    6555             :         // this semicolon with that modifier.
    6556             :         MUST_MATCH_TOKEN_MOD(TokenKind::Semi, TokenStream::Operand, JSMSG_SEMI_AFTER_FOR_INIT);
    6557           0 : 
    6558             :         TokenKind tt;
    6559             :         if (!tokenStream.peekToken(&tt, TokenStream::Operand))
    6560         346 :             return null();
    6561         346 : 
    6562             :         Node test;
    6563             :         if (tt == TokenKind::Semi) {
    6564             :             test = null();
    6565           0 :         } else {
    6566             :             test = expr(InAllowed, yieldHandling, TripledotProhibited);
    6567         354 :             if (!test)
    6568             :                 return null();
    6569             :         }
    6570             : 
    6571         354 :         MUST_MATCH_TOKEN_MOD(TokenKind::Semi, TokenStream::Operand, JSMSG_SEMI_AFTER_FOR_COND);
    6572             : 
    6573             :         if (!tokenStream.peekToken(&tt, TokenStream::Operand))
    6574         344 :             return null();
    6575         344 : 
    6576             :         Node update;
    6577             :         if (tt == TokenKind::Rp) {
    6578             :             update = null();
    6579           0 :         } else {
    6580             :             update = expr(InAllowed, yieldHandling, TripledotProhibited);
    6581        1062 :             if (!update)
    6582         708 :                 return null();
    6583           0 :         }
    6584             : 
    6585             :         MUST_MATCH_TOKEN_MOD(TokenKind::Rp, TokenStream::Operand, JSMSG_PAREN_AFTER_FOR_CTRL);
    6586           0 : 
    6587             :         TokenPos headPos(begin, pos().end);
    6588             :         forHead = handler.newForHead(init, test, update, headPos);
    6589             :         if (!forHead)
    6590             :             return null();
    6591           0 :     } else {
    6592             :         MOZ_ASSERT(headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf);
    6593             : 
    6594           0 :         // |target| is the LeftHandSideExpression or declaration to which the
    6595           0 :         // per-iteration value (an arbitrary value exposed by the iteration
    6596             :         // protocol, or a string naming a property) is assigned.
    6597        1116 :         Node target = startNode;
    6598             : 
    6599             :         // Parse the rest of the for-in/of head.
    6600             :         if (headKind == ParseNodeKind::ForIn)
    6601             :             stmt.refineForKind(StatementKind::ForInLoop);
    6602        1256 :         else
    6603             :             stmt.refineForKind(StatementKind::ForOfLoop);
    6604        3768 : 
    6605        1256 :         // Parser::declaration consumed everything up to the closing ')'.  That
    6606           0 :         // token follows an {Assignment,}Expression and so must be interpreted
    6607             :         // as an operand to be consistent with normal expression tokenizing.
    6608             :         MUST_MATCH_TOKEN_MOD(TokenKind::Rp, TokenStream::Operand, JSMSG_PAREN_AFTER_FOR_CTRL);
    6609             : 
    6610        1610 :         TokenPos headPos(begin, pos().end);
    6611        1610 :         forHead = handler.newForInOrOfHead(headKind, target, iteratedExpr, headPos);
    6612             :         if (!forHead)
    6613             :             return null();
    6614           0 :     }
    6615        1610 : 
    6616             :     Node body = statement(yieldHandling);
    6617             :     if (!body)
    6618           0 :         return null();
    6619        1422 : 
    6620             :     Node forLoop = handler.newForStatement(begin, forHead, body, iflags);
    6621             :     if (!forLoop)
    6622             :         return null();
    6623             : 
    6624             :     if (forLoopLexicalScope)
    6625             :         return finishLexicalScope(*forLoopLexicalScope, forLoop);
    6626           0 : 
    6627             :     return forLoop;
    6628         796 : }
    6629         796 : 
    6630             : template <class ParseHandler, typename CharT>
    6631           0 : typename ParseHandler::Node
    6632             : GeneralParser<ParseHandler, CharT>::switchStatement(YieldHandling yieldHandling)
    6633         398 : {
    6634         398 :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Switch));
    6635             :     uint32_t begin = pos().begin;
    6636             : 
    6637         398 :     MUST_MATCH_TOKEN(TokenKind::Lp, JSMSG_PAREN_BEFORE_SWITCH);
    6638           0 : 
    6639             :     Node discriminant = exprInParens(InAllowed, yieldHandling, TripledotProhibited);
    6640           0 :     if (!discriminant)
    6641           0 :         return null();
    6642         398 : 
    6643             :     MUST_MATCH_TOKEN_MOD(TokenKind::Rp, TokenStream::Operand, JSMSG_PAREN_AFTER_SWITCH);
    6644             :     MUST_MATCH_TOKEN(TokenKind::Lc, JSMSG_CURLY_BEFORE_SWITCH);
    6645           0 : 
    6646           0 :     ParseContext::Statement stmt(pc, StatementKind::Switch);
    6647             :     ParseContext::Scope scope(this);
    6648             :     if (!scope.init(pc))
    6649             :         return null();
    6650             : 
    6651        1839 :     Node caseList = handler.newStatementList(pos());
    6652           0 :     if (!caseList)
    6653             :         return null();
    6654           0 : 
    6655             :     bool seenDefault = false;
    6656        3678 :     TokenKind tt;
    6657             :     while (true) {
    6658             :         if (!tokenStream.getToken(&tt, TokenStream::Operand))
    6659        1839 :             return null();
    6660             :         if (tt == TokenKind::Rc)
    6661         130 :             break;
    6662           0 :         uint32_t caseBegin = pos().begin;
    6663           0 : 
    6664             :         Node caseExpr;
    6665             :         switch (tt) {
    6666             :           case TokenKind::Default:
    6667             :             if (seenDefault) {
    6668             :                 error(JSMSG_TOO_MANY_DEFAULTS);
    6669             :                 return null();
    6670        1709 :             }
    6671           0 :             seenDefault = true;
    6672             :             caseExpr = null();  // The default case has pn_left == nullptr.
    6673             :             break;
    6674             : 
    6675             :           case TokenKind::Case:
    6676           0 :             caseExpr = expr(InAllowed, yieldHandling, TripledotProhibited);
    6677           0 :             if (!caseExpr)
    6678             :                 return null();
    6679             :             break;
    6680        1839 : 
    6681             :           default:
    6682           0 :             error(JSMSG_BAD_SWITCH);
    6683           0 :             return null();
    6684             :         }
    6685             : 
    6686           0 :         MUST_MATCH_TOKEN_MOD(TokenKind::Colon, TokenStream::Operand, JSMSG_COLON_AFTER_CASE);
    6687           0 : 
    6688           0 :         Node body = handler.newStatementList(pos());
    6689           0 :         if (!body)
    6690        5044 :             return null();
    6691             : 
    6692           0 :         bool afterReturn = false;
    6693             :         bool warnedAboutStatementsAfterReturn = false;
    6694           0 :         uint32_t statementBegin = 0;
    6695           0 :         while (true) {
    6696             :             if (!tokenStream.peekToken(&tt, TokenStream::Operand))
    6697             :                 return null();
    6698           1 :             if (tt == TokenKind::Rc || tt == TokenKind::Case || tt == TokenKind::Default)
    6699           1 :                 break;
    6700             :             if (afterReturn) {
    6701           0 :                 if (!tokenStream.peekOffset(&statementBegin, TokenStream::Operand))
    6702           0 :                     return null();
    6703           3 :             }
    6704           0 :             Node stmt = statementListItem(yieldHandling);
    6705             :             if (!stmt)
    6706             :                 return null();
    6707             :             if (!warnedAboutStatementsAfterReturn) {
    6708             :                 if (afterReturn) {
    6709        6404 :                     if (!handler.isStatementPermittedAfterReturnStatement(stmt)) {
    6710           0 :                         if (!warningAt(statementBegin, JSMSG_STMT_AFTER_RETURN))
    6711             :                             return null();
    6712             : 
    6713           0 :                         warnedAboutStatementsAfterReturn = true;
    6714             :                     }
    6715             :                 } else if (handler.isReturnStatement(stmt)) {
    6716           0 :                     afterReturn = true;
    6717        1839 :                 }
    6718             :             }
    6719        1839 :             handler.addStatementToList(body, stmt);
    6720             :         }
    6721             : 
    6722           0 :         Node casepn = handler.newCaseOrDefault(caseBegin, caseExpr, body);
    6723         398 :         if (!casepn)
    6724             :             return null();
    6725             :         handler.addCaseStatementToList(caseList, casepn);
    6726         796 :     }
    6727             : 
    6728           0 :     caseList = finishLexicalScope(scope, caseList);
    6729             :     if (!caseList)
    6730             :         return null();
    6731             : 
    6732             :     handler.setEndPosition(caseList, pos().end);
    6733         266 : 
    6734             :     return handler.newSwitchStatement(begin, discriminant, caseList);
    6735           0 : }
    6736         532 : 
    6737             : template <class ParseHandler, typename CharT>
    6738           0 : typename ParseHandler::Node
    6739         266 : GeneralParser<ParseHandler, CharT>::continueStatement(YieldHandling yieldHandling)
    6740             : {
    6741             :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Continue));
    6742         266 :     uint32_t begin = pos().begin;
    6743         266 : 
    6744           0 :     RootedPropertyName label(context);
    6745             :     if (!matchLabel(yieldHandling, &label))
    6746           0 :         return null();
    6747           0 : 
    6748             :     auto validity = pc->checkContinueStatement(label);
    6749           0 :     if (validity.isErr()) {
    6750           0 :         switch (validity.unwrapErr()) {
    6751             :           case ParseContext::ContinueStatementError::NotInALoop:
    6752             :             errorAt(begin, JSMSG_BAD_CONTINUE);
    6753             :             break;
    6754             :           case ParseContext::ContinueStatementError::LabelNotFound:
    6755           0 :             error(JSMSG_LABEL_NOT_FOUND);
    6756             :             break;
    6757             :         }
    6758           0 :         return null();
    6759             :     }
    6760             : 
    6761             :     if (!matchOrInsertSemicolon())
    6762             :         return null();
    6763        1262 : 
    6764             :     return handler.newContinueStatement(label, TokenPos(begin, pos().end));
    6765        2524 : }
    6766        2524 : 
    6767             : template <class ParseHandler, typename CharT>
    6768        3786 : typename ParseHandler::Node
    6769        1262 : GeneralParser<ParseHandler, CharT>::breakStatement(YieldHandling yieldHandling)
    6770             : {
    6771             :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Break));
    6772             :     uint32_t begin = pos().begin;
    6773             : 
    6774             :     RootedPropertyName label(context);
    6775           0 :     if (!matchLabel(yieldHandling, &label))
    6776           0 :         return null();
    6777           0 : 
    6778           0 :     // Labeled 'break' statements target the nearest labeled statements (could
    6779             :     // be any kind) with the same label. Unlabeled 'break' statements target
    6780           0 :     // the innermost loop or switch statement.
    6781           0 :     if (label) {
    6782           0 :         auto hasSameLabel = [&label](ParseContext::LabelStatement* stmt) {
    6783             :             return stmt->label() == label;
    6784             :         };
    6785             : 
    6786        1903 :         if (!pc->template findInnermostStatement<ParseContext::LabelStatement>(hasSameLabel)) {
    6787           0 :             error(JSMSG_LABEL_NOT_FOUND);
    6788             :             return null();
    6789           0 :         }
    6790           0 :     } else {
    6791             :         auto isBreakTarget = [](ParseContext::Statement* stmt) {
    6792             :             return StatementKindIsUnlabeledBreakTarget(stmt->kind());
    6793             :         };
    6794             : 
    6795        1262 :         if (!pc->findInnermostStatement(isBreakTarget)) {
    6796             :             errorAt(begin, JSMSG_TOUGH_BREAK);
    6797             :             return null();
    6798           0 :         }
    6799             :     }
    6800             : 
    6801             :     if (!matchOrInsertSemicolon())
    6802             :         return null();
    6803       10295 : 
    6804             :     return handler.newBreakStatement(label, TokenPos(begin, pos().end));
    6805       20590 : }
    6806       20590 : 
    6807             : template <class ParseHandler, typename CharT>
    6808       20590 : typename ParseHandler::Node
    6809       20590 : GeneralParser<ParseHandler, CharT>::returnStatement(YieldHandling yieldHandling)
    6810             : {
    6811             :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Return));
    6812             :     uint32_t begin = pos().begin;
    6813             : 
    6814             :     MOZ_ASSERT(pc->isFunctionBox());
    6815           0 :     pc->functionBox()->usesReturn = true;
    6816       10295 : 
    6817             :     // Parse an optional operand.
    6818           0 :     //
    6819             :     // This is ugly, but we don't want to require a semicolon.
    6820             :     Node exprNode;
    6821             :     TokenKind tt = TokenKind::Eof;
    6822             :     if (!tokenStream.peekTokenSameLine(&tt, TokenStream::Operand))
    6823             :         return null();
    6824             :     switch (tt) {
    6825             :       case TokenKind::Eol:
    6826        8766 :       case TokenKind::Eof:
    6827           0 :       case TokenKind::Semi:
    6828             :       case TokenKind::Rc:
    6829             :         exprNode = null();
    6830             :         break;
    6831             :       default: {
    6832       10295 :         exprNode = expr(InAllowed, yieldHandling, TripledotProhibited);
    6833             :         if (!exprNode)
    6834             :             return null();
    6835       30885 :       }
    6836             :     }
    6837             : 
    6838             :     if (!matchOrInsertSemicolon())
    6839             :         return null();
    6840          53 : 
    6841             :     return handler.newReturnStatement(exprNode, TokenPos(begin, pos().end));
    6842         106 : }
    6843         106 : 
    6844             : template <class ParseHandler, typename CharT>
    6845         106 : typename ParseHandler::Node
    6846         106 : GeneralParser<ParseHandler, CharT>::yieldExpression(InHandling inHandling)
    6847             : {
    6848          53 :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Yield));
    6849             :     uint32_t begin = pos().begin;
    6850             : 
    6851          53 :     MOZ_ASSERT(pc->isGenerator());
    6852           0 :     MOZ_ASSERT(pc->isFunctionBox());
    6853          53 : 
    6854             :     pc->lastYieldOffset = begin;
    6855           0 : 
    6856             :     Node exprNode;
    6857             :     ParseNodeKind kind = ParseNodeKind::Yield;
    6858             :     TokenKind tt = TokenKind::Eof;
    6859             :     if (!tokenStream.peekTokenSameLine(&tt, TokenStream::Operand))
    6860             :         return null();
    6861             :     switch (tt) {
    6862             :       // TokenKind::Eol is special; it implements the [no LineTerminator here]
    6863             :       // quirk in the grammar.
    6864             :       case TokenKind::Eol:
    6865             :       // The rest of these make up the complete set of tokens that can
    6866             :       // appear after any of the places where AssignmentExpression is used
    6867             :       // throughout the grammar.  Conveniently, none of them can also be the
    6868             :       // start an expression.
    6869             :       case TokenKind::Eof:
    6870             :       case TokenKind::Semi:
    6871             :       case TokenKind::Rc:
    6872           0 :       case TokenKind::Rb:
    6873           0 :       case TokenKind::Rp:
    6874           0 :       case TokenKind::Colon:
    6875             :       case TokenKind::Comma:
    6876           9 :       case TokenKind::In:
    6877           9 :         // No value.
    6878             :         exprNode = null();
    6879             :         anyChars.addModifierException(TokenStream::NoneIsOperand);
    6880          53 :         break;
    6881          53 :       case TokenKind::Mul:
    6882             :         kind = ParseNodeKind::YieldStar;
    6883             :         tokenStream.consumeKnownToken(TokenKind::Mul, TokenStream::Operand);
    6884           0 :         MOZ_FALLTHROUGH;
    6885           0 :       default:
    6886           0 :         exprNode = assignExpr(inHandling, YieldIsKeyword, TripledotProhibited);
    6887             :         if (!exprNode)
    6888             :             return null();
    6889             :     }
    6890             :     if (kind == ParseNodeKind::YieldStar)
    6891           0 :         return handler.newYieldStarExpression(begin, exprNode);
    6892             :     return handler.newYieldExpression(begin, exprNode);
    6893           0 : }
    6894           0 : 
    6895             : template <class ParseHandler, typename CharT>
    6896             : typename ParseHandler::Node
    6897             : GeneralParser<ParseHandler, CharT>::withStatement(YieldHandling yieldHandling)
    6898             : {
    6899             :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::With));
    6900             :     uint32_t begin = pos().begin;
    6901           0 : 
    6902           0 :     // Usually we want the constructs forbidden in strict mode code to be a
    6903             :     // subset of those that ContextOptions::extraWarnings() warns about, and we
    6904             :     // use strictModeError directly.  But while 'with' is forbidden in strict
    6905             :     // mode code, it doesn't even merit a warning in non-strict code.  See
    6906           0 :     // https://bugzilla.mozilla.org/show_bug.cgi?id=514576#c1.
    6907             :     if (pc->sc()->strict()) {
    6908           0 :         if (!strictModeError(JSMSG_STRICT_CODE_WITH))
    6909           0 :             return null();
    6910             :     }
    6911             : 
    6912           0 :     MUST_MATCH_TOKEN(TokenKind::Lp, JSMSG_PAREN_BEFORE_WITH);
    6913             : 
    6914             :     Node objectExpr = exprInParens(InAllowed, yieldHandling, TripledotProhibited);
    6915             :     if (!objectExpr)
    6916           0 :         return null();
    6917           0 : 
    6918           0 :     MUST_MATCH_TOKEN_MOD(TokenKind::Rp, TokenStream::Operand, JSMSG_PAREN_AFTER_WITH);
    6919           0 : 
    6920             :     Node innerBlock;
    6921             :     {
    6922           0 :         ParseContext::Statement stmt(pc, StatementKind::With);
    6923             :         innerBlock = statement(yieldHandling);
    6924           0 :         if (!innerBlock)
    6925             :             return null();
    6926             :     }
    6927             : 
    6928             :     pc->sc()->setBindingsAccessedDynamically();
    6929           0 : 
    6930             :     return handler.newWithStatement(begin, objectExpr, innerBlock);
    6931             : }
    6932           0 : 
    6933             : template <class ParseHandler, typename CharT>
    6934             : typename ParseHandler::Node
    6935           0 : GeneralParser<ParseHandler, CharT>::labeledItem(YieldHandling yieldHandling)
    6936             : {
    6937           0 :     TokenKind tt;
    6938             :     if (!tokenStream.getToken(&tt, TokenStream::Operand))
    6939             :         return null();
    6940             : 
    6941             :     if (tt == TokenKind::Function) {
    6942           0 :         TokenKind next;
    6943           0 :         if (!tokenStream.peekToken(&next))
    6944           0 :             return null();
    6945             : 
    6946             :         // GeneratorDeclaration is only matched by HoistableDeclaration in
    6947             :         // StatementListItem, so generators can't be inside labels.
    6948             :         if (next == TokenKind::Mul) {
    6949             :             error(JSMSG_GENERATOR_LABEL);
    6950           0 :             return null();
    6951           0 :         }
    6952           0 : 
    6953             :         // Per 13.13.1 it's a syntax error if LabelledItem: FunctionDeclaration
    6954             :         // is ever matched.  Per Annex B.3.2 that modifies this text, this
    6955           0 :         // applies only to strict mode code.
    6956             :         if (pc->sc()->strict()) {
    6957             :             error(JSMSG_FUNCTION_LABEL);
    6958           0 :             return null();
    6959           0 :         }
    6960             : 
    6961             :         return functionStmt(pos().begin, yieldHandling, NameRequired);
    6962             :     }
    6963             : 
    6964           0 :     anyChars.ungetToken();
    6965             :     return statement(yieldHandling);
    6966           0 : }
    6967           0 : 
    6968             : template <class ParseHandler, typename CharT>
    6969             : typename ParseHandler::Node
    6970           0 : GeneralParser<ParseHandler, CharT>::labeledStatement(YieldHandling yieldHandling)
    6971           0 : {
    6972           0 :     RootedPropertyName label(context, labelIdentifier(yieldHandling));
    6973             :     if (!label)
    6974           0 :         return null();
    6975             : 
    6976           0 :     auto hasSameLabel = [&label](ParseContext::LabelStatement* stmt) {
    6977           0 :         return stmt->label() == label;
    6978           0 :     };
    6979             : 
    6980             :     uint32_t begin = pos().begin;
    6981           0 : 
    6982             :     if (pc->template findInnermostStatement<ParseContext::LabelStatement>(hasSameLabel)) {
    6983             :         errorAt(begin, JSMSG_DUPLICATE_LABEL);
    6984           0 :         return null();
    6985           0 :     }
    6986           0 : 
    6987             :     tokenStream.consumeKnownToken(TokenKind::Colon);
    6988             : 
    6989           0 :     /* Push a label struct and parse the statement. */
    6990             :     ParseContext::LabelStatement stmt(pc, label);
    6991             :     Node pn = labeledItem(yieldHandling);
    6992             :     if (!pn)
    6993             :         return null();
    6994        1327 : 
    6995             :     return handler.newLabeledStatement(label, pn, begin);
    6996           0 : }
    6997           0 : 
    6998             : template <class ParseHandler, typename CharT>
    6999             : typename ParseHandler::Node
    7000        1327 : GeneralParser<ParseHandler, CharT>::throwStatement(YieldHandling yieldHandling)
    7001           0 : {
    7002             :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Throw));
    7003        1327 :     uint32_t begin = pos().begin;
    7004           0 : 
    7005           0 :     /* ECMA-262 Edition 3 says 'throw [no LineTerminator here] Expr'. */
    7006             :     TokenKind tt = TokenKind::Eof;
    7007        1327 :     if (!tokenStream.peekTokenSameLine(&tt, TokenStream::Operand))
    7008           0 :         return null();
    7009           0 :     if (tt == TokenKind::Eof || tt == TokenKind::Semi || tt == TokenKind::Rc) {
    7010             :         error(JSMSG_MISSING_EXPR_AFTER_THROW);
    7011             :         return null();
    7012           0 :     }
    7013           0 :     if (tt == TokenKind::Eol) {
    7014             :         error(JSMSG_LINE_BREAK_AFTER_THROW);
    7015             :         return null();
    7016           0 :     }
    7017             : 
    7018             :     Node throwExpr = expr(InAllowed, yieldHandling, TripledotProhibited);
    7019           0 :     if (!throwExpr)
    7020             :         return null();
    7021             : 
    7022             :     if (!matchOrInsertSemicolon())
    7023             :         return null();
    7024           0 : 
    7025             :     return handler.newThrowStatement(throwExpr, TokenPos(begin, pos().end));
    7026        2148 : }
    7027        2148 : 
    7028             : template <class ParseHandler, typename CharT>
    7029             : typename ParseHandler::Node
    7030             : GeneralParser<ParseHandler, CharT>::tryStatement(YieldHandling yieldHandling)
    7031             : {
    7032             :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Try));
    7033             :     uint32_t begin = pos().begin;
    7034             : 
    7035             :     /*
    7036             :      * try nodes are ternary.
    7037             :      * kid1 is the try statement
    7038             :      * kid2 is the catch node list or null
    7039             :      * kid3 is the finally statement
    7040             :      *
    7041             :      * catch nodes are binary.
    7042             :      * left is the catch-name/pattern or null
    7043             :      * right is the catch block
    7044             :      *
    7045             :      * catch lvalue nodes are either:
    7046             :      *   a single identifier
    7047             :      *   TokenKind::Rb or TokenKind::Rc for a destructuring left-hand side
    7048        1074 :      *
    7049             :      * finally nodes are TokenKind::Lc statement lists.
    7050        2148 :      */
    7051             : 
    7052        3222 :     Node innerBlock;
    7053        2148 :     {
    7054        1074 :         MUST_MATCH_TOKEN(TokenKind::Lc, JSMSG_CURLY_BEFORE_TRY);
    7055           0 : 
    7056             :         uint32_t openedPos = pos().begin;
    7057        1074 : 
    7058        1074 :         ParseContext::Statement stmt(pc, StatementKind::Try);
    7059             :         ParseContext::Scope scope(this);
    7060             :         if (!scope.init(pc))
    7061        1074 :             return null();
    7062           0 : 
    7063             :         innerBlock = statementList(yieldHandling);
    7064             :         if (!innerBlock)
    7065           0 :             return null();
    7066             : 
    7067             :         innerBlock = finishLexicalScope(scope, innerBlock);
    7068             :         if (!innerBlock)
    7069             :             return null();
    7070           0 : 
    7071             :         MUST_MATCH_TOKEN_MOD_WITH_REPORT(TokenKind::Rc, TokenStream::Operand,
    7072        1074 :                                          reportMissingClosing(JSMSG_CURLY_AFTER_TRY,
    7073             :                                                               JSMSG_CURLY_OPENED, openedPos));
    7074           0 :     }
    7075             : 
    7076             :     Node catchScope = null();
    7077             :     TokenKind tt;
    7078             :     if (!tokenStream.getToken(&tt))
    7079        3009 :         return null();
    7080        2006 :     if (tt == TokenKind::Catch) {
    7081        1003 :         /*
    7082           0 :          * Create a lexical scope node around the whole catch clause,
    7083             :          * including the head.
    7084             :          */
    7085             :         ParseContext::Statement stmt(pc, StatementKind::Catch);
    7086             :         ParseContext::Scope scope(this);
    7087             :         if (!scope.init(pc))
    7088             :             return null();
    7089             : 
    7090             :         /*
    7091           0 :          * Legal catch forms are:
    7092             :          *   catch (lhs) {
    7093             :          *   catch {
    7094             :          * where lhs is a name or a destructuring left-hand side.
    7095        1003 :          */
    7096             :         bool omittedBinding;
    7097             :         if (!tokenStream.matchToken(&omittedBinding, TokenKind::Lc))
    7098        1003 :             return null();
    7099             : 
    7100        1003 :         Node catchName;
    7101             :         if (omittedBinding) {
    7102        1003 :             catchName = null();
    7103             :         } else {
    7104             :             MUST_MATCH_TOKEN(TokenKind::Lp, JSMSG_PAREN_BEFORE_CATCH);
    7105           1 : 
    7106             :             if (!tokenStream.getToken(&tt))
    7107           0 :                 return null();
    7108             :             switch (tt) {
    7109             :               case TokenKind::Lb:
    7110             :               case TokenKind::Lc:
    7111             :                 catchName = destructuringDeclaration(DeclarationKind::CatchParameter,
    7112           0 :                                                      yieldHandling, tt);
    7113           0 :                 if (!catchName)
    7114           0 :                     return null();
    7115             :                 break;
    7116             : 
    7117           0 :               default: {
    7118             :                 if (!TokenKindIsPossibleIdentifierName(tt)) {
    7119           0 :                     error(JSMSG_CATCH_IDENTIFIER);
    7120             :                     return null();
    7121             :                 }
    7122             : 
    7123             :                 catchName = bindingIdentifier(DeclarationKind::SimpleCatchParameter,
    7124             :                                               yieldHandling);
    7125           0 :                 if (!catchName)
    7126             :                     return null();
    7127        2006 :                 break;
    7128             :               }
    7129             :             }
    7130        1003 : 
    7131           0 :             MUST_MATCH_TOKEN_MOD(TokenKind::Rp, TokenStream::Operand, JSMSG_PAREN_AFTER_CATCH);
    7132             : 
    7133             :             MUST_MATCH_TOKEN(TokenKind::Lc, JSMSG_CURLY_BEFORE_CATCH);
    7134        1003 :         }
    7135        1003 : 
    7136             :         Node catchBody = catchBlockStatement(yieldHandling, scope);
    7137             :         if (!catchBody)
    7138        1003 :             return null();
    7139             : 
    7140        2006 :         catchScope = finishLexicalScope(scope, catchBody);
    7141             :         if (!catchScope)
    7142           0 :             return null();
    7143             : 
    7144             :         if (!handler.setupCatchScope(catchScope, catchName, catchBody))
    7145             :             return null();
    7146           0 :         handler.setEndPosition(catchScope, pos().end);
    7147             : 
    7148        1074 :         if (!tokenStream.getToken(&tt, TokenStream::Operand))
    7149         100 :             return null();
    7150             :     }
    7151         200 : 
    7152             :     Node finallyBlock = null();
    7153         300 : 
    7154           0 :     if (tt == TokenKind::Finally) {
    7155         100 :         MUST_MATCH_TOKEN(TokenKind::Lc, JSMSG_CURLY_BEFORE_FINALLY);
    7156           0 : 
    7157             :         uint32_t openedPos = pos().begin;
    7158           0 : 
    7159         100 :         ParseContext::Statement stmt(pc, StatementKind::Finally);
    7160             :         ParseContext::Scope scope(this);
    7161             :         if (!scope.init(pc))
    7162         100 :             return null();
    7163           0 : 
    7164             :         finallyBlock = statementList(yieldHandling);
    7165             :         if (!finallyBlock)
    7166           0 :             return null();
    7167             : 
    7168             :         finallyBlock = finishLexicalScope(scope, finallyBlock);
    7169             :         if (!finallyBlock)
    7170           0 :             return null();
    7171             : 
    7172        1074 :         MUST_MATCH_TOKEN_MOD_WITH_REPORT(TokenKind::Rc, TokenStream::Operand,
    7173           0 :                                          reportMissingClosing(JSMSG_CURLY_AFTER_FINALLY,
    7174           0 :                                                               JSMSG_CURLY_OPENED, openedPos));
    7175             :     } else {
    7176             :         anyChars.ungetToken();
    7177        2148 :     }
    7178             :     if (!catchScope && !finallyBlock) {
    7179             :         error(JSMSG_CATCH_OR_FINALLY);
    7180             :         return null();
    7181             :     }
    7182           0 : 
    7183             :     return handler.newTryStatement(begin, innerBlock, catchScope, finallyBlock);
    7184             : }
    7185           0 : 
    7186             : template <class ParseHandler, typename CharT>
    7187        3009 : typename ParseHandler::Node
    7188             : GeneralParser<ParseHandler, CharT>::catchBlockStatement(YieldHandling yieldHandling,
    7189             :                                                         ParseContext::Scope& catchParamScope)
    7190             : {
    7191             :     uint32_t openedPos = pos().begin;
    7192             : 
    7193        2006 :     ParseContext::Statement stmt(pc, StatementKind::Block);
    7194           0 : 
    7195             :     // ES 13.15.7 CatchClauseEvaluation
    7196             :     //
    7197             :     // Step 8 means that the body of a catch block always has an additional
    7198             :     // lexical scope.
    7199           0 :     ParseContext::Scope scope(this);
    7200             :     if (!scope.init(pc))
    7201             :         return null();
    7202        1003 : 
    7203        1003 :     // The catch parameter names cannot be redeclared inside the catch
    7204             :     // block, so declare the name in the inner scope.
    7205             :     if (!scope.addCatchParameters(pc, catchParamScope))
    7206           0 :         return null();
    7207             : 
    7208             :     Node list = statementList(yieldHandling);
    7209             :     if (!list)
    7210             :         return null();
    7211             : 
    7212        1003 :     MUST_MATCH_TOKEN_MOD_WITH_REPORT(TokenKind::Rc, TokenStream::Operand,
    7213        1003 :                                      reportMissingClosing(JSMSG_CURLY_AFTER_CATCH,
    7214             :                                                           JSMSG_CURLY_OPENED, openedPos));
    7215             : 
    7216             :     // The catch parameter names are not bound in the body scope, so remove
    7217             :     // them before generating bindings.
    7218           0 :     scope.removeCatchParameters(pc, catchParamScope);
    7219             :     return finishLexicalScope(scope, list);
    7220           0 : }
    7221           0 : 
    7222           0 : template <class ParseHandler, typename CharT>
    7223             : typename ParseHandler::Node
    7224           0 : GeneralParser<ParseHandler, CharT>::debuggerStatement()
    7225             : {
    7226           0 :     TokenPos p;
    7227           0 :     p.begin = pos().begin;
    7228             :     if (!matchOrInsertSemicolon())
    7229           0 :         return null();
    7230             :     p.end = pos().end;
    7231             : 
    7232             :     pc->sc()->setBindingsAccessedDynamically();
    7233           0 :     pc->sc()->setHasDebuggerStatement();
    7234             : 
    7235        6032 :     return handler.newDebuggerStatement(p);
    7236             : }
    7237             : 
    7238             : static AccessorType
    7239           0 : ToAccessorType(PropertyType propType)
    7240             : {
    7241             :     switch (propType) {
    7242             :       case PropertyType::Getter:
    7243             :         return AccessorType::Getter;
    7244             :       case PropertyType::Setter:
    7245             :         return AccessorType::Setter;
    7246             :       case PropertyType::Normal:
    7247           0 :       case PropertyType::Method:
    7248             :       case PropertyType::GeneratorMethod:
    7249           0 :       case PropertyType::AsyncMethod:
    7250             :       case PropertyType::AsyncGeneratorMethod:
    7251             :       case PropertyType::Constructor:
    7252             :       case PropertyType::DerivedConstructor:
    7253             :         return AccessorType::None;
    7254             :       default:
    7255         212 :         MOZ_CRASH("unexpected property type");
    7256             :     }
    7257             : }
    7258             : 
    7259           0 : template <class ParseHandler, typename CharT>
    7260             : typename ParseHandler::Node
    7261           1 : GeneralParser<ParseHandler, CharT>::classDefinition(YieldHandling yieldHandling,
    7262         212 :                                                     ClassContext classContext,
    7263             :                                                     DefaultHandling defaultHandling)
    7264             : {
    7265         212 :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Class));
    7266             : 
    7267             :     uint32_t classStartOffset = pos().begin;
    7268         636 :     bool savedStrictness = setLocalStrictMode(true);
    7269         424 : 
    7270         384 :     TokenKind tt;
    7271           0 :     if (!tokenStream.getToken(&tt))
    7272             :         return null();
    7273           0 : 
    7274           0 :     RootedPropertyName name(context);
    7275           0 :     if (TokenKindIsPossibleIdentifier(tt)) {
    7276           0 :         name = bindingIdentifier(yieldHandling);
    7277             :         if (!name)
    7278             :             return null();
    7279           0 :     } else if (classContext == ClassStatement) {
    7280           0 :         if (defaultHandling == AllowDefaultName) {
    7281             :             name = context->names().default_;
    7282             :             anyChars.ungetToken();
    7283             :         } else {
    7284          20 :             // Class statements must have a bound name
    7285             :             error(JSMSG_UNNAMED_CLASS_STMT);
    7286             :             return null();
    7287             :         }
    7288             :     } else {
    7289         424 :         // Make sure to put it back, whatever it was
    7290             :         anyChars.ungetToken();
    7291           0 :     }
    7292             : 
    7293             :     // Push a ParseContext::ClassStatement to keep track of the constructor
    7294             :     // funbox.
    7295         424 :     ParseContext::ClassStatement classStmt(pc);
    7296           0 : 
    7297         212 :     RootedAtom propAtom(context);
    7298         192 : 
    7299         192 :     // A named class creates a new lexical scope with a const binding of the
    7300         192 :     // class name for the "inner name".
    7301             :     Maybe<ParseContext::Statement> innerScopeStmt;
    7302             :     Maybe<ParseContext::Scope> innerScope;
    7303             :     if (name) {
    7304             :         innerScopeStmt.emplace(pc, StatementKind::Block);
    7305             :         innerScope.emplace(this);
    7306             :         if (!innerScope->init(pc))
    7307           0 :             return null();
    7308             :     }
    7309           0 : 
    7310             :     // Because the binding definitions keep track of their blockId, we need to
    7311           0 :     // create at least the inner binding later. Keep track of the name's position
    7312             :     // in order to provide it for the nodes created later.
    7313         212 :     TokenPos namePos = pos();
    7314         116 : 
    7315             :     Node classHeritage = null();
    7316         116 :     bool hasHeritage;
    7317         116 :     if (!tokenStream.matchToken(&hasHeritage, TokenKind::Extends))
    7318             :         return null();
    7319             :     if (hasHeritage) {
    7320             :         if (!tokenStream.getToken(&tt))
    7321           0 :             return null();
    7322             :         classHeritage = memberExpr(yieldHandling, TripledotProhibited, tt);
    7323           0 :         if (!classHeritage)
    7324         212 :             return null();
    7325             :     }
    7326             : 
    7327             :     MUST_MATCH_TOKEN(TokenKind::Lc, JSMSG_CURLY_BEFORE_CLASS);
    7328             : 
    7329             :     Node classMethods = handler.newClassMethodList(pos().begin);
    7330        1763 :     if (!classMethods)
    7331           0 :         return null();
    7332        1763 : 
    7333             :     Maybe<DeclarationKind> declKind = Nothing();
    7334             :     for (;;) {
    7335           0 :         TokenKind tt;
    7336           0 :         if (!tokenStream.getToken(&tt))
    7337             :             return null();
    7338        1551 :         if (tt == TokenKind::Rc)
    7339        1551 :             break;
    7340          57 : 
    7341             :         if (tt == TokenKind::Semi)
    7342           0 :             continue;
    7343           0 : 
    7344           0 :         bool isStatic = false;
    7345           0 :         if (tt == TokenKind::Static) {
    7346             :             if (!tokenStream.peekToken(&tt))
    7347             :                 return null();
    7348           0 :             if (tt == TokenKind::Rc) {
    7349             :                 tokenStream.consumeKnownToken(tt);
    7350             :                 error(JSMSG_UNEXPECTED_TOKEN, "property name", TokenKindToDesc(tt));
    7351           0 :                 return null();
    7352             :             }
    7353        1494 : 
    7354             :             if (tt != TokenKind::Lp)
    7355             :                 isStatic = true;
    7356             :             else
    7357           1 :                 anyChars.ungetToken();
    7358             :         } else {
    7359             :             anyChars.ungetToken();
    7360             :         }
    7361        1551 : 
    7362        1551 :         uint32_t nameOffset;
    7363             :         if (!tokenStream.peekOffset(&nameOffset))
    7364             :             return null();
    7365           0 : 
    7366             :         PropertyType propType;
    7367        1551 :         Node propName = propertyName(yieldHandling, declKind, classMethods, &propType, &propAtom);
    7368             :         if (!propName)
    7369             :             return null();
    7370           0 : 
    7371           0 :         if (propType != PropertyType::Getter && propType != PropertyType::Setter &&
    7372             :             propType != PropertyType::Method && propType != PropertyType::GeneratorMethod &&
    7373             :             propType != PropertyType::AsyncMethod &&
    7374           0 :             propType != PropertyType::AsyncGeneratorMethod)
    7375        1551 :         {
    7376         164 :             errorAt(nameOffset, JSMSG_BAD_METHOD_DEF);
    7377           0 :             return null();
    7378           0 :         }
    7379             : 
    7380         164 :         bool isConstructor = !isStatic && propAtom == context->names().constructor;
    7381           0 :         if (isConstructor) {
    7382           0 :             if (propType != PropertyType::Method) {
    7383             :                 errorAt(nameOffset, JSMSG_BAD_METHOD_DEF);
    7384         164 :                 return null();
    7385        1558 :             }
    7386           0 :             if (classStmt.constructorBox) {
    7387           0 :                 errorAt(nameOffset, JSMSG_DUPLICATE_PROPERTY, "constructor");
    7388             :                 return null();
    7389             :             }
    7390           0 :             propType = hasHeritage ? PropertyType::DerivedConstructor : PropertyType::Constructor;
    7391        1551 :         } else if (isStatic && propAtom == context->names().prototype) {
    7392             :             errorAt(nameOffset, JSMSG_BAD_METHOD_DEF);
    7393             :             return null();
    7394           0 :         }
    7395         542 : 
    7396           0 :         RootedAtom funName(context);
    7397           0 :         switch (propType) {
    7398             :           case PropertyType::Getter:
    7399             :           case PropertyType::Setter:
    7400             :             if (!anyChars.isCurrentTokenType(TokenKind::Rb)) {
    7401             :                 funName = prefixAccessorName(propType, propAtom);
    7402           0 :                 if (!funName)
    7403           0 :                     return null();
    7404             :             }
    7405        2232 :             break;
    7406             :           case PropertyType::Constructor:
    7407             :           case PropertyType::DerivedConstructor:
    7408             :             funName = name;
    7409             :             break;
    7410             :           default:
    7411             :             if (!anyChars.isCurrentTokenType(TokenKind::Rb))
    7412        3102 :                 funName = propAtom;
    7413        1551 :         }
    7414           0 : 
    7415             :         // Calling toString on constructors need to return the source text for
    7416             :         // the entire class. The end offset is unknown at this point in
    7417           0 :         // parsing and will be amended when class parsing finishes below.
    7418        1551 :         Node fn = methodDefinition(isConstructor ? classStartOffset : nameOffset,
    7419             :                                    propType, funName);
    7420             :         if (!fn)
    7421             :             return null();
    7422             : 
    7423             :         AccessorType atype = ToAccessorType(propType);
    7424           0 :         if (!handler.addClassMethodDefinition(classMethods, propName, fn, atype, isStatic))
    7425           0 :             return null();
    7426           0 :     }
    7427           0 : 
    7428         164 :     // Amend the toStringEnd offset for the constructor now that we've
    7429             :     // finished parsing the class.
    7430             :     uint32_t classEndOffset = pos().end;
    7431         212 :     if (FunctionBox* ctorbox = classStmt.constructorBox) {
    7432         212 :         if (ctorbox->function()->isInterpretedLazy())
    7433         212 :             ctorbox->function()->lazyScript()->setToStringEnd(classEndOffset);
    7434             :         ctorbox->toStringEnd = classEndOffset;
    7435         192 :     }
    7436             : 
    7437             :     Node nameNode = null();
    7438           0 :     Node methodsOrBlock = classMethods;
    7439           1 :     if (name) {
    7440             :         // The inner name is immutable.
    7441             :         if (!noteDeclaredName(name, DeclarationKind::Const, namePos))
    7442         192 :             return null();
    7443           0 : 
    7444             :         Node innerName = newName(name, namePos);
    7445             :         if (!innerName)
    7446         192 :             return null();
    7447             : 
    7448             :         Node classBlock = finishLexicalScope(*innerScope, classMethods);
    7449         192 :         if (!classBlock)
    7450           0 :             return null();
    7451             : 
    7452         192 :         methodsOrBlock = classBlock;
    7453         192 : 
    7454             :         // Pop the inner scope.
    7455           0 :         innerScope.reset();
    7456             :         innerScopeStmt.reset();
    7457             : 
    7458           0 :         Node outerName = null();
    7459         165 :         if (classContext == ClassStatement) {
    7460             :             // The outer name is mutable.
    7461             :             if (!noteDeclaredName(name, DeclarationKind::Class, namePos))
    7462             :                 return null();
    7463         384 : 
    7464           0 :             outerName = newName(name, namePos);
    7465             :             if (!outerName)
    7466             :                 return null();
    7467             :         }
    7468         212 : 
    7469             :         nameNode = handler.newClassNames(outerName, innerName, namePos);
    7470             :         if (!nameNode)
    7471           0 :             return null();
    7472             :     }
    7473             : 
    7474             :     MOZ_ALWAYS_TRUE(setLocalStrictMode(savedStrictness));
    7475           0 : 
    7476             :     return handler.newClass(nameNode, classHeritage, methodsOrBlock,
    7477       21462 :                             TokenPos(classStartOffset, classEndOffset));
    7478       10731 : }
    7479             : 
    7480           0 : bool
    7481             : ParserBase::nextTokenContinuesLetDeclaration(TokenKind next)
    7482             : {
    7483           0 :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Let));
    7484             :     MOZ_ASSERT(anyChars.nextToken().type == next);
    7485             : 
    7486             :     TokenStreamShared::verifyConsistentModifier(TokenStreamShared::None, anyChars.nextToken());
    7487             : 
    7488             :     // Destructuring continues a let declaration.
    7489             :     if (next == TokenKind::Lb || next == TokenKind::Lc)
    7490             :         return true;
    7491             : 
    7492             :     // A "let" edge case deserves special comment.  Consider this:
    7493             :     //
    7494             :     //   let     // not an ASI opportunity
    7495             :     //   let;
    7496             :     //
    7497             :     // Static semantics in §13.3.1.1 turn a LexicalDeclaration that binds
    7498             :     // "let" into an early error.  Does this retroactively permit ASI so
    7499             :     // that we should parse this as two ExpressionStatements?   No.  ASI
    7500             :     // resolves during parsing.  Static semantics only apply to the full
    7501             :     // parse tree with ASI applied.  No backsies!
    7502             : 
    7503        3415 :     // Otherwise a let declaration must have a name.
    7504             :     return TokenKindIsPossibleIdentifier(next);
    7505        3415 : }
    7506        3415 : 
    7507             : template <class ParseHandler, typename CharT>
    7508        3415 : typename ParseHandler::Node
    7509             : GeneralParser<ParseHandler, CharT>::variableStatement(YieldHandling yieldHandling)
    7510        3415 : {
    7511             :     Node vars = declarationList(yieldHandling, ParseNodeKind::Var);
    7512             :     if (!vars)
    7513             :         return null();
    7514             :     if (!matchOrInsertSemicolon())
    7515           0 :         return null();
    7516             :     return vars;
    7517           0 : }
    7518             : 
    7519       17100 : template <class ParseHandler, typename CharT>
    7520             : typename ParseHandler::Node
    7521             : GeneralParser<ParseHandler, CharT>::statement(YieldHandling yieldHandling)
    7522             : {
    7523       17100 :     MOZ_ASSERT(checkOptionsCalled);
    7524             : 
    7525             :     if (!CheckRecursionLimit(context))
    7526       17100 :         return null();
    7527             : 
    7528             :     TokenKind tt;
    7529           0 :     if (!tokenStream.getToken(&tt, TokenStream::Operand))
    7530             :         return null();
    7531             : 
    7532             :     switch (tt) {
    7533           1 :       // BlockStatement[?Yield, ?Return]
    7534             :       case TokenKind::Lc:
    7535             :         return blockStatement(yieldHandling);
    7536             : 
    7537           3 :       // VariableStatement[?Yield]
    7538             :       case TokenKind::Var:
    7539             :         return variableStatement(yieldHandling);
    7540             : 
    7541             :       // EmptyStatement
    7542             :       case TokenKind::Semi:
    7543             :         return handler.newEmptyStatement(pos());
    7544             : 
    7545           0 :       // ExpressionStatement[?Yield].
    7546             : 
    7547             :       case TokenKind::Yield: {
    7548           0 :         // Don't use a ternary operator here due to obscure linker issues
    7549             :         // around using static consts in the arms of a ternary.
    7550             :         Modifier modifier;
    7551           8 :         if (yieldExpressionsSupported())
    7552             :             modifier = TokenStream::Operand;
    7553             :         else
    7554           8 :             modifier = TokenStream::None;
    7555           0 : 
    7556             :         TokenKind next;
    7557           0 :         if (!tokenStream.peekToken(&next, modifier))
    7558             :             return null();
    7559             : 
    7560             :         if (next == TokenKind::Colon)
    7561             :             return labeledStatement(yieldHandling);
    7562        1873 : 
    7563           0 :         return expressionStatement(yieldHandling);
    7564             :       }
    7565        3690 : 
    7566           0 :       default: {
    7567             :         // Avoid getting next token with None.
    7568             :         if (tt == TokenKind::Await && pc->isAsync())
    7569           0 :             return expressionStatement(yieldHandling);
    7570             : 
    7571             :         if (!TokenKindIsPossibleIdentifier(tt))
    7572             :             return expressionStatement(yieldHandling);
    7573             : 
    7574           0 :         TokenKind next;
    7575           0 :         if (!tokenStream.peekToken(&next))
    7576             :             return null();
    7577           0 : 
    7578             :         // |let| here can only be an Identifier, not a declaration.  Give nicer
    7579             :         // errors for declaration-looking typos.
    7580           0 :         if (tt == TokenKind::Let) {
    7581             :             bool forbiddenLetDeclaration = false;
    7582             : 
    7583             :             if (next == TokenKind::Lb) {
    7584             :                 // Enforce ExpressionStatement's 'let [' lookahead restriction.
    7585             :                 forbiddenLetDeclaration = true;
    7586             :             } else if (next == TokenKind::Lc || TokenKindIsPossibleIdentifier(next)) {
    7587             :                 // 'let {' and 'let foo' aren't completely forbidden, if ASI
    7588           0 :                 // causes 'let' to be the entire Statement.  But if they're
    7589           0 :                 // same-line, we can aggressively give a better error message.
    7590             :                 //
    7591           0 :                 // Note that this ignores 'yield' as TokenKind::Yield: we'll handle it
    7592             :                 // correctly but with a worse error message.
    7593             :                 TokenKind nextSameLine;
    7594             :                 if (!tokenStream.peekTokenSameLine(&nextSameLine))
    7595           0 :                     return null();
    7596             : 
    7597             :                 MOZ_ASSERT(TokenKindIsPossibleIdentifier(nextSameLine) ||
    7598           0 :                            nextSameLine == TokenKind::Lc ||
    7599           0 :                            nextSameLine == TokenKind::Eol);
    7600           0 : 
    7601             :                 forbiddenLetDeclaration = nextSameLine != TokenKind::Eol;
    7602        1484 :             }
    7603             : 
    7604             :             if (forbiddenLetDeclaration) {
    7605             :                 error(JSMSG_FORBIDDEN_AS_STATEMENT, "lexical declarations");
    7606             :                 return null();
    7607             :             }
    7608             :         } else if (tt == TokenKind::Async) {
    7609             :             // Peek only on the same line: ExpressionStatement's lookahead
    7610             :             // restriction is phrased as
    7611             :             //
    7612             :             //   [lookahead ∉ { {, function, async [no LineTerminator here] function, class, let [ }]
    7613             :             //
    7614           0 :             // meaning that code like this is valid:
    7615           0 :             //
    7616             :             //   if (true)
    7617           0 :             //     async       // ASI opportunity
    7618           0 :             //   function clownshoes() {}
    7619           0 :             TokenKind maybeFunction;
    7620             :             if (!tokenStream.peekTokenSameLine(&maybeFunction))
    7621             :                 return null();
    7622             : 
    7623             :             if (maybeFunction == TokenKind::Function) {
    7624             :                 error(JSMSG_FORBIDDEN_AS_STATEMENT, "async function declarations");
    7625             :                 return null();
    7626             :             }
    7627             : 
    7628        1484 :             // Otherwise this |async| begins an ExpressionStatement or is a
    7629           0 :             // label name.
    7630             :         }
    7631           0 : 
    7632             :         // NOTE: It's unfortunately allowed to have a label named 'let' in
    7633             :         //       non-strict code.  💯
    7634             :         if (next == TokenKind::Colon)
    7635           0 :             return labeledStatement(yieldHandling);
    7636             : 
    7637             :         return expressionStatement(yieldHandling);
    7638             :       }
    7639          10 : 
    7640             :       case TokenKind::New:
    7641             :         return expressionStatement(yieldHandling, PredictInvoked);
    7642             : 
    7643             :       // IfStatement[?Yield, ?Return]
    7644             :       case TokenKind::If:
    7645             :         return ifStatement(yieldHandling);
    7646             : 
    7647           0 :       // BreakableStatement[?Yield, ?Return]
    7648             :       //
    7649             :       // BreakableStatement[Yield, Return]:
    7650           0 :       //   IterationStatement[?Yield, ?Return]
    7651             :       //   SwitchStatement[?Yield, ?Return]
    7652             :       case TokenKind::Do:
    7653           0 :         return doWhileStatement(yieldHandling);
    7654             : 
    7655             :       case TokenKind::While:
    7656           0 :         return whileStatement(yieldHandling);
    7657             : 
    7658             :       case TokenKind::For:
    7659             :         return forStatement(yieldHandling);
    7660          78 : 
    7661             :       case TokenKind::Switch:
    7662             :         return switchStatement(yieldHandling);
    7663             : 
    7664          46 :       // ContinueStatement[?Yield]
    7665             :       case TokenKind::Continue:
    7666             :         return continueStatement(yieldHandling);
    7667             : 
    7668             :       // BreakStatement[?Yield]
    7669             :       case TokenKind::Break:
    7670             :         return breakStatement(yieldHandling);
    7671        1884 : 
    7672           0 :       // [+Return] ReturnStatement[?Yield]
    7673           0 :       case TokenKind::Return:
    7674             :         // The Return parameter is only used here, and the effect is easily
    7675         942 :         // detected this way, so don't bother passing around an extra parameter
    7676             :         // everywhere.
    7677             :         if (!pc->isFunctionBox()) {
    7678             :             error(JSMSG_BAD_RETURN_OR_YIELD, js_return_str);
    7679           0 :             return null();
    7680             :         }
    7681             :         return returnStatement(yieldHandling);
    7682             : 
    7683             :       // WithStatement[?Yield, ?Return]
    7684             :       case TokenKind::With:
    7685             :         return withStatement(yieldHandling);
    7686         224 : 
    7687             :       // LabelledStatement[?Yield, ?Return]
    7688             :       // This is really handled by default and TokenKind::Yield cases above.
    7689             : 
    7690           1 :       // ThrowStatement[?Yield]
    7691             :       case TokenKind::Throw:
    7692             :         return throwStatement(yieldHandling);
    7693             : 
    7694           0 :       // TryStatement[?Yield, ?Return]
    7695             :       case TokenKind::Try:
    7696             :         return tryStatement(yieldHandling);
    7697             : 
    7698             :       // DebuggerStatement
    7699             :       case TokenKind::Debugger:
    7700           0 :         return debuggerStatement();
    7701           0 : 
    7702             :       // |function| is forbidden by lookahead restriction (unless as child
    7703             :       // statement of |if| or |else|, but Parser::consequentOrAlternative
    7704             :       // handles that).
    7705           0 :       case TokenKind::Function:
    7706           0 :         error(JSMSG_FORBIDDEN_AS_STATEMENT, "function declarations");
    7707             :         return null();
    7708             : 
    7709             :       // |class| is also forbidden by lookahead restriction.
    7710           0 :       case TokenKind::Class:
    7711             :         error(JSMSG_FORBIDDEN_AS_STATEMENT, "classes");
    7712             :         return null();
    7713             : 
    7714           0 :       // ImportDeclaration (only inside modules)
    7715             :       case TokenKind::Import:
    7716             :         return importDeclarationOrImportMeta(yieldHandling);
    7717             : 
    7718             :       // ExportDeclaration (only inside modules)
    7719           0 :       case TokenKind::Export:
    7720           0 :         return exportDeclaration();
    7721             : 
    7722             :       // Miscellaneous error cases arguably better caught here than elsewhere.
    7723           0 : 
    7724           0 :       case TokenKind::Catch:
    7725             :         error(JSMSG_CATCH_WITHOUT_TRY);
    7726             :         return null();
    7727             : 
    7728             :       case TokenKind::Finally:
    7729             :         error(JSMSG_FINALLY_WITHOUT_TRY);
    7730             :         return null();
    7731             : 
    7732           1 :       // NOTE: default case handled in the ExpressionStatement section.
    7733             :     }
    7734             : }
    7735           1 : 
    7736             : template <class ParseHandler, typename CharT>
    7737       76114 : typename ParseHandler::Node
    7738             : GeneralParser<ParseHandler, CharT>::statementListItem(YieldHandling yieldHandling,
    7739             :                                                       bool canHaveDirectives /* = false */)
    7740             : {
    7741       76114 :     MOZ_ASSERT(checkOptionsCalled);
    7742             : 
    7743             :     if (!CheckRecursionLimit(context))
    7744           0 :         return null();
    7745             : 
    7746             :     TokenKind tt;
    7747           0 :     if (!tokenStream.getToken(&tt, TokenStream::Operand))
    7748             :         return null();
    7749             : 
    7750             :     switch (tt) {
    7751        3414 :       // BlockStatement[?Yield, ?Return]
    7752             :       case TokenKind::Lc:
    7753             :         return blockStatement(yieldHandling);
    7754             : 
    7755           3 :       // VariableStatement[?Yield]
    7756             :       case TokenKind::Var:
    7757             :         return variableStatement(yieldHandling);
    7758             : 
    7759             :       // EmptyStatement
    7760             :       case TokenKind::Semi:
    7761             :         return handler.newEmptyStatement(pos());
    7762         253 : 
    7763           0 :       // ExpressionStatement[?Yield].
    7764           0 :       //
    7765           0 :       // These should probably be handled by a single ExpressionStatement
    7766             :       // function in a default, not split up this way.
    7767             :       case TokenKind::String:
    7768         253 :         if (!canHaveDirectives && anyChars.currentToken().atom() == context->names().useAsm) {
    7769             :             if (!abortIfSyntaxParser())
    7770             :                 return null();
    7771             :             if (!warning(JSMSG_USE_ASM_DIRECTIVE_FAIL))
    7772             :                 return null();
    7773             :         }
    7774           0 :         return expressionStatement(yieldHandling);
    7775             : 
    7776             :       case TokenKind::Yield: {
    7777           0 :         // Don't use a ternary operator here due to obscure linker issues
    7778             :         // around using static consts in the arms of a ternary.
    7779             :         Modifier modifier;
    7780           0 :         if (yieldExpressionsSupported())
    7781             :             modifier = TokenStream::Operand;
    7782             :         else
    7783          45 :             modifier = TokenStream::None;
    7784           0 : 
    7785             :         TokenKind next;
    7786           0 :         if (!tokenStream.peekToken(&next, modifier))
    7787             :             return null();
    7788             : 
    7789             :         if (next == TokenKind::Colon)
    7790             :             return labeledStatement(yieldHandling);
    7791       40067 : 
    7792           0 :         return expressionStatement(yieldHandling);
    7793             :       }
    7794       77742 : 
    7795           0 :       default: {
    7796             :         // Avoid getting next token with None.
    7797             :         if (tt == TokenKind::Await && pc->isAsync())
    7798           0 :             return expressionStatement(yieldHandling);
    7799             : 
    7800             :         if (!TokenKindIsPossibleIdentifier(tt))
    7801       29182 :             return expressionStatement(yieldHandling);
    7802        9405 : 
    7803             :         TokenKind next;
    7804           0 :         if (!tokenStream.peekToken(&next))
    7805          59 :             return null();
    7806           0 : 
    7807           0 :         if (tt == TokenKind::Let && nextTokenContinuesLetDeclaration(next))
    7808          59 :             return lexicalDeclaration(yieldHandling, DeclarationKind::Let);
    7809         118 : 
    7810           0 :         if (tt == TokenKind::Async) {
    7811             :             TokenKind nextSameLine = TokenKind::Eof;
    7812          59 :             if (!tokenStream.peekTokenSameLine(&nextSameLine))
    7813             :                 return null();
    7814             :             if (nextSameLine == TokenKind::Function) {
    7815             :                 uint32_t toStringStart = pos().begin;
    7816           0 :                 tokenStream.consumeKnownToken(TokenKind::Function);
    7817           0 :                 return functionStmt(toStringStart, yieldHandling, NameRequired,
    7818             :                                     FunctionAsyncKind::AsyncFunction);
    7819           0 :             }
    7820             :         }
    7821             : 
    7822             :         if (next == TokenKind::Colon)
    7823          22 :             return labeledStatement(yieldHandling);
    7824             : 
    7825             :         return expressionStatement(yieldHandling);
    7826             :       }
    7827       12856 : 
    7828             :       case TokenKind::New:
    7829             :         return expressionStatement(yieldHandling, PredictInvoked);
    7830             : 
    7831             :       // IfStatement[?Yield, ?Return]
    7832             :       case TokenKind::If:
    7833             :         return ifStatement(yieldHandling);
    7834             : 
    7835           0 :       // BreakableStatement[?Yield, ?Return]
    7836             :       //
    7837             :       // BreakableStatement[Yield, Return]:
    7838         268 :       //   IterationStatement[?Yield, ?Return]
    7839             :       //   SwitchStatement[?Yield, ?Return]
    7840             :       case TokenKind::Do:
    7841        1610 :         return doWhileStatement(yieldHandling);
    7842             : 
    7843             :       case TokenKind::While:
    7844         398 :         return whileStatement(yieldHandling);
    7845             : 
    7846             :       case TokenKind::For:
    7847             :         return forStatement(yieldHandling);
    7848         188 : 
    7849             :       case TokenKind::Switch:
    7850             :         return switchStatement(yieldHandling);
    7851             : 
    7852        1216 :       // ContinueStatement[?Yield]
    7853             :       case TokenKind::Continue:
    7854             :         return continueStatement(yieldHandling);
    7855             : 
    7856             :       // BreakStatement[?Yield]
    7857             :       case TokenKind::Break:
    7858             :         return breakStatement(yieldHandling);
    7859       18706 : 
    7860           0 :       // [+Return] ReturnStatement[?Yield]
    7861           0 :       case TokenKind::Return:
    7862             :         // The Return parameter is only used here, and the effect is easily
    7863        9353 :         // detected this way, so don't bother passing around an extra parameter
    7864             :         // everywhere.
    7865             :         if (!pc->isFunctionBox()) {
    7866             :             error(JSMSG_BAD_RETURN_OR_YIELD, js_return_str);
    7867           0 :             return null();
    7868             :         }
    7869             :         return returnStatement(yieldHandling);
    7870             : 
    7871             :       // WithStatement[?Yield, ?Return]
    7872             :       case TokenKind::With:
    7873             :         return withStatement(yieldHandling);
    7874        1103 : 
    7875             :       // LabelledStatement[?Yield, ?Return]
    7876             :       // This is really handled by default and TokenKind::Yield cases above.
    7877             : 
    7878        1073 :       // ThrowStatement[?Yield]
    7879             :       case TokenKind::Throw:
    7880             :         return throwStatement(yieldHandling);
    7881             : 
    7882           0 :       // TryStatement[?Yield, ?Return]
    7883             :       case TokenKind::Try:
    7884             :         return tryStatement(yieldHandling);
    7885             : 
    7886             :       // DebuggerStatement
    7887             :       case TokenKind::Debugger:
    7888        3152 :         return debuggerStatement();
    7889             : 
    7890             :       // Declaration[Yield]:
    7891             : 
    7892         165 :       //   HoistableDeclaration[?Yield, ~Default]
    7893             :       case TokenKind::Function:
    7894             :         return functionStmt(pos().begin, yieldHandling, NameRequired);
    7895             : 
    7896             :       //   ClassDeclaration[?Yield, ~Default]
    7897             :       case TokenKind::Class:
    7898             :         return classDefinition(yieldHandling, ClassStatement, NameRequired);
    7899        2593 : 
    7900             :       //   LexicalDeclaration[In, ?Yield]
    7901             :       //     LetOrConst BindingList[?In, ?Yield]
    7902             :       case TokenKind::Const:
    7903           0 :         // [In] is the default behavior, because for-loops specially parse
    7904             :         // their heads to handle |in| in this situation.
    7905             :         return lexicalDeclaration(yieldHandling, DeclarationKind::Const);
    7906             : 
    7907           0 :       // ImportDeclaration (only inside modules)
    7908             :       case TokenKind::Import:
    7909             :         return importDeclarationOrImportMeta(yieldHandling);
    7910             : 
    7911             :       // ExportDeclaration (only inside modules)
    7912           0 :       case TokenKind::Export:
    7913           0 :         return exportDeclaration();
    7914             : 
    7915             :       // Miscellaneous error cases arguably better caught here than elsewhere.
    7916           0 : 
    7917           0 :       case TokenKind::Catch:
    7918             :         error(JSMSG_CATCH_WITHOUT_TRY);
    7919             :         return null();
    7920             : 
    7921             :       case TokenKind::Finally:
    7922             :         error(JSMSG_FINALLY_WITHOUT_TRY);
    7923             :         return null();
    7924             : 
    7925           0 :       // NOTE: default case handled in the ExpressionStatement section.
    7926             :     }
    7927             : }
    7928             : 
    7929             : template <class ParseHandler, typename CharT>
    7930             : typename ParseHandler::Node
    7931       66592 : GeneralParser<ParseHandler, CharT>::expr(InHandling inHandling, YieldHandling yieldHandling,
    7932       66592 :                                          TripledotHandling tripledotHandling,
    7933             :                                          PossibleError* possibleError /* = nullptr */,
    7934             :                                          InvokedPrediction invoked /* = PredictUninvoked */)
    7935             : {
    7936       66592 :     Node pn = assignExpr(inHandling, yieldHandling, tripledotHandling,
    7937             :                          possibleError, invoked);
    7938       66592 :     if (!pn)
    7939             :         return null();
    7940             : 
    7941         568 :     bool matched;
    7942         284 :     if (!tokenStream.matchToken(&matched, TokenKind::Comma, TokenStream::Operand))
    7943             :         return null();
    7944           0 :     if (!matched)
    7945             :         return pn;
    7946             : 
    7947             :     Node seq = handler.newCommaExpressionList(pn);
    7948             :     if (!seq)
    7949             :         return null();
    7950           0 :     while (true) {
    7951             :         // Trailing comma before the closing parenthesis is valid in an arrow
    7952         335 :         // function parameters list: `(a, b, ) => body`. Check if we are
    7953           0 :         // directly under CoverParenthesizedExpressionAndArrowParameterList,
    7954             :         // and the next two tokens are closing parenthesis and arrow. If all
    7955         335 :         // are present allow the trailing comma.
    7956           0 :         if (tripledotHandling == TripledotAllowed) {
    7957             :             TokenKind tt;
    7958           0 :             if (!tokenStream.peekToken(&tt, TokenStream::Operand))
    7959             :                 return null();
    7960           0 : 
    7961           0 :             if (tt == TokenKind::Rp) {
    7962           0 :                 tokenStream.consumeKnownToken(TokenKind::Rp, TokenStream::Operand);
    7963             : 
    7964             :                 if (!tokenStream.peekToken(&tt))
    7965           0 :                     return null();
    7966           0 :                 if (tt != TokenKind::Arrow) {
    7967             :                     error(JSMSG_UNEXPECTED_TOKEN, "expression", TokenKindToDesc(TokenKind::Rp));
    7968             :                     return null();
    7969             :                 }
    7970             : 
    7971             :                 anyChars.ungetToken();  // put back right paren
    7972             :                 break;
    7973             :             }
    7974           0 :         }
    7975         344 : 
    7976             :         // Additional calls to assignExpr should not reuse the possibleError
    7977           0 :         // which had been passed into the function. Otherwise we would lose
    7978             :         // information needed to determine whether or not we're dealing with
    7979             :         // a non-recoverable situation.
    7980         344 :         PossibleError possibleErrorInner(*this);
    7981             :         pn = assignExpr(inHandling, yieldHandling, tripledotHandling,
    7982          10 :                         &possibleErrorInner);
    7983             :         if (!pn)
    7984             :             return null();
    7985         334 : 
    7986             :         if (!possibleError) {
    7987             :             // Report any pending expression error.
    7988         688 :             if (!possibleErrorInner.checkForExpressionError())
    7989             :                 return null();
    7990         344 :         } else {
    7991             :             possibleErrorInner.transferErrorsTo(possibleError);
    7992           0 :         }
    7993             : 
    7994             :         handler.addList(seq, pn);
    7995         284 : 
    7996             :         if (!tokenStream.matchToken(&matched, TokenKind::Comma, TokenStream::Operand))
    7997             :             return null();
    7998             :         if (!matched)
    7999       19984 :             break;
    8000             :     }
    8001       19984 :     return seq;
    8002           0 : }
    8003             : 
    8004             : static ParseNodeKind
    8005             : BinaryOpTokenKindToParseNodeKind(TokenKind tok)
    8006             : {
    8007             :     MOZ_ASSERT(TokenKindIsBinaryOp(tok));
    8008             :     return ParseNodeKind(size_t(ParseNodeKind::BinOpFirst) + (size_t(tok) - size_t(TokenKind::BinOpFirst)));
    8009             : }
    8010             : 
    8011             : static const int PrecedenceTable[] = {
    8012             :     1, /* ParseNodeKind::PipeLine */
    8013             :     2, /* ParseNodeKind::Or */
    8014             :     3, /* ParseNodeKind::And */
    8015             :     4, /* ParseNodeKind::BitOr */
    8016             :     5, /* ParseNodeKind::BitXor */
    8017             :     6, /* ParseNodeKind::BitAnd */
    8018             :     7, /* ParseNodeKind::StrictEq */
    8019             :     7, /* ParseNodeKind::Eq */
    8020             :     7, /* ParseNodeKind::StrictNe */
    8021             :     7, /* ParseNodeKind::Ne */
    8022             :     8, /* ParseNodeKind::Lt */
    8023             :     8, /* ParseNodeKind::Le */
    8024             :     8, /* ParseNodeKind::Gt */
    8025             :     8, /* ParseNodeKind::Ge */
    8026             :     8, /* ParseNodeKind::InstanceOf */
    8027             :     8, /* ParseNodeKind::In */
    8028             :     9, /* ParseNodeKind::Lsh */
    8029             :     9, /* ParseNodeKind::Rsh */
    8030             :     9, /* ParseNodeKind::Ursh */
    8031             :     10, /* ParseNodeKind::Add */
    8032             :     10, /* ParseNodeKind::Sub */
    8033             :     11, /* ParseNodeKind::Star */
    8034             :     11, /* ParseNodeKind::Div */
    8035             :     11, /* ParseNodeKind::Mod */
    8036       44188 :     12  /* ParseNodeKind::Pow */
    8037             : };
    8038             : 
    8039             : static const int PRECEDENCE_CLASSES = 12;
    8040             : 
    8041       44188 : static int
    8042             : Precedence(ParseNodeKind pnk)
    8043             : {
    8044       29229 :     // Everything binds tighter than ParseNodeKind::Limit, because we want
    8045       29229 :     // to reduce all nodes to a single node when we reach a token that is not
    8046       29229 :     // another binary operator.
    8047             :     if (pnk == ParseNodeKind::Limit)
    8048             :         return 0;
    8049             : 
    8050             :     MOZ_ASSERT(pnk >= ParseNodeKind::BinOpFirst);
    8051      112567 :     MOZ_ASSERT(pnk <= ParseNodeKind::BinOpLast);
    8052             :     return PrecedenceTable[size_t(pnk) - size_t(ParseNodeKind::BinOpFirst)];
    8053             : }
    8054             : 
    8055             : template <class ParseHandler, typename CharT>
    8056             : MOZ_ALWAYS_INLINE typename ParseHandler::Node
    8057             : GeneralParser<ParseHandler, CharT>::orExpr(InHandling inHandling, YieldHandling yieldHandling,
    8058             :                                            TripledotHandling tripledotHandling,
    8059             :                                            PossibleError* possibleError,
    8060             :                                            InvokedPrediction invoked /* = PredictUninvoked */)
    8061             : {
    8062             :     // Shift-reduce parser for the binary operator part of the JS expression
    8063           0 :     // syntax.
    8064             : 
    8065       19985 :     // Conceptually there's just one stack, a stack of pairs (lhs, op).
    8066      132552 :     // It's implemented using two separate arrays, though.
    8067      132552 :     Node nodeStack[PRECEDENCE_CLASSES];
    8068           0 :     ParseNodeKind kindStack[PRECEDENCE_CLASSES];
    8069             :     int depth = 0;
    8070             :     Node pn;
    8071             :     for (;;) {
    8072             :         pn = unaryExpr(yieldHandling, tripledotHandling, possibleError, invoked);
    8073      132553 :         if (!pn)
    8074             :             return null();
    8075             : 
    8076             :         // If a binary operator follows, consume it and compute the
    8077           0 :         // corresponding operator.
    8078             :         TokenKind tok;
    8079             :         if (!tokenStream.getToken(&tok))
    8080           0 :             return null();
    8081             : 
    8082             :         ParseNodeKind pnk;
    8083       19984 :         if (tok == TokenKind::In ? inHandling == InAllowed : TokenKindIsBinaryOp(tok)) {
    8084           0 :             // We're definitely not in a destructuring context, so report any
    8085           0 :             // pending expression error now.
    8086             :             if (possibleError && !possibleError->checkForExpressionError())
    8087       19984 :                 return null();
    8088             :             // Report an error for unary expressions on the LHS of **.
    8089           0 :             if (tok == TokenKind::Pow && handler.isUnparenthesizedUnaryExpression(pn)) {
    8090      112568 :                 error(JSMSG_BAD_POW_LEFTSIDE);
    8091             :                 return null();
    8092             :             }
    8093             :             pnk = BinaryOpTokenKindToParseNodeKind(tok);
    8094      132552 :         } else {
    8095             :             tok = TokenKind::Eof;
    8096             :             pnk = ParseNodeKind::Limit;
    8097             :         }
    8098             : 
    8099             :         // From this point on, destructuring defaults are definitely an error.
    8100             :         possibleError = nullptr;
    8101             : 
    8102             :         // If pnk has precedence less than or equal to another operator on the
    8103      152537 :         // stack, reduce. This combines nodes on the stack until we form the
    8104       19985 :         // actual lhs of pnk.
    8105       19985 :         //
    8106           0 :         // The >= in this condition works because it is appendOrCreateList's
    8107       19985 :         // job to decide if the operator in question is left- or
    8108             :         // right-associative, and build the corresponding tree.
    8109             :         while (depth > 0 && Precedence(kindStack[depth - 1]) >= Precedence(pnk)) {
    8110             :             depth--;
    8111      132552 :             ParseNodeKind combiningPnk = kindStack[depth];
    8112             :             pn = handler.appendOrCreateList(combiningPnk, nodeStack[depth], pn, pc);
    8113             :             if (!pn)
    8114       19985 :                 return null();
    8115           0 :         }
    8116           0 : 
    8117           0 :         if (pnk == ParseNodeKind::Limit)
    8118             :             break;
    8119             : 
    8120             :         nodeStack[depth] = pn;
    8121             :         kindStack[depth] = pnk;
    8122             :         depth++;
    8123           0 :         MOZ_ASSERT(depth <= PRECEDENCE_CLASSES);
    8124      112567 :     }
    8125             : 
    8126           0 :     // When the next token is no longer a binary operator, it's potentially the
    8127             :     // start of an expression.  Add a modifier exception so that the next token
    8128             :     // modifier can be Operand.
    8129             :     anyChars.ungetToken();
    8130             :     anyChars.addModifierException(TokenStream::OperandIsNone);
    8131             : 
    8132      112567 :     MOZ_ASSERT(depth == 0);
    8133             :     return pn;
    8134             : }
    8135             : 
    8136             : template <class ParseHandler, typename CharT>
    8137      112567 : MOZ_ALWAYS_INLINE typename ParseHandler::Node
    8138           0 : GeneralParser<ParseHandler, CharT>::condExpr(InHandling inHandling, YieldHandling yieldHandling,
    8139             :                                              TripledotHandling tripledotHandling,
    8140             :                                              PossibleError* possibleError,
    8141             :                                              InvokedPrediction invoked /* = PredictUninvoked */)
    8142      112567 : {
    8143             :     Node condition = orExpr(inHandling, yieldHandling, tripledotHandling, possibleError, invoked);
    8144           0 :     if (!condition)
    8145             :         return null();
    8146             : 
    8147         972 :     bool matched;
    8148         972 :     if (!tokenStream.matchToken(&matched, TokenKind::Hook))
    8149             :         return null();
    8150             :     if (!matched)
    8151         972 :         return condition;
    8152             : 
    8153         972 :     Node thenExpr = assignExpr(InAllowed, yieldHandling, TripledotProhibited);
    8154           0 :     if (!thenExpr)
    8155             :         return null();
    8156             : 
    8157        1944 :     MUST_MATCH_TOKEN_MOD(TokenKind::Colon, TokenStream::Operand, JSMSG_COLON_IN_COND);
    8158             : 
    8159             :     Node elseExpr = assignExpr(inHandling, yieldHandling, TripledotProhibited);
    8160             :     if (!elseExpr)
    8161             :         return null();
    8162      176088 : 
    8163             :     return handler.newConditional(condition, thenExpr, elseExpr);
    8164             : }
    8165             : 
    8166             : template <class ParseHandler, typename CharT>
    8167      176088 : typename ParseHandler::Node
    8168             : GeneralParser<ParseHandler, CharT>::assignExpr(InHandling inHandling, YieldHandling yieldHandling,
    8169             :                                                TripledotHandling tripledotHandling,
    8170             :                                                PossibleError* possibleError /* = nullptr */,
    8171             :                                                InvokedPrediction invoked /* = PredictUninvoked */)
    8172             : {
    8173             :     if (!CheckRecursionLimit(context))
    8174             :         return null();
    8175             : 
    8176             :     // It's very common at this point to have a "detectably simple" expression,
    8177             :     // i.e. a name/number/string token followed by one of the following tokens
    8178             :     // that obviously isn't part of an expression: , ; : ) ] }
    8179             :     //
    8180             :     // (In Parsemark this happens 81.4% of the time;  in code with large
    8181             :     // numeric arrays, such as some Kraken benchmarks, it happens more often.)
    8182      176091 :     //
    8183             :     // In such cases, we can avoid the full expression parsing route through
    8184             :     // assignExpr(), condExpr(), orExpr(), unaryExpr(), memberExpr(), and
    8185      352178 :     // primaryExpr().
    8186             : 
    8187             :     TokenKind firstToken;
    8188             :     if (!tokenStream.getToken(&firstToken, TokenStream::Operand))
    8189             :         return null();
    8190             : 
    8191             :     TokenPos exprPos = pos();
    8192      176089 : 
    8193       94409 :     bool endsExpr;
    8194             : 
    8195       94409 :     // This only handles identifiers that *never* have special meaning anywhere
    8196       70368 :     // in the language.  Contextual keywords, reserved words in strict mode,
    8197           0 :     // and other hard cases are handled outside this fast path.
    8198             :     if (firstToken == TokenKind::Name) {
    8199             :         if (!tokenStream.nextTokenEndsExpr(&endsExpr))
    8200       35184 :             return null();
    8201             :         if (endsExpr) {
    8202             :             Rooted<PropertyName*> name(context, identifierReference(yieldHandling));
    8203             :             if (!name)
    8204           0 :                 return null();
    8205           0 : 
    8206             :             return identifierReference(name);
    8207           0 :         }
    8208           0 :     }
    8209             : 
    8210             :     if (firstToken == TokenKind::Number) {
    8211      135859 :         if (!tokenStream.nextTokenEndsExpr(&endsExpr))
    8212           0 :             return null();
    8213             :         if (endsExpr)
    8214       24879 :             return newNumber(anyChars.currentToken());
    8215       23221 :     }
    8216             : 
    8217             :     if (firstToken == TokenKind::String) {
    8218      112691 :         if (!tokenStream.nextTokenEndsExpr(&endsExpr))
    8219           0 :             return null();
    8220             :         if (endsExpr)
    8221      112585 :             return stringLiteral();
    8222      112585 :     }
    8223           0 : 
    8224           0 :     if (firstToken == TokenKind::Yield && yieldExpressionsSupported())
    8225           0 :         return yieldExpression(inHandling);
    8226             : 
    8227           0 :     bool maybeAsyncArrow = false;
    8228          19 :     if (firstToken == TokenKind::Async) {
    8229             :         TokenKind nextSameLine = TokenKind::Eof;
    8230             :         if (!tokenStream.peekTokenSameLine(&nextSameLine))
    8231           0 :             return null();
    8232             : 
    8233             :         if (TokenKindIsPossibleIdentifier(nextSameLine))
    8234             :             maybeAsyncArrow = true;
    8235           0 :     }
    8236             : 
    8237           0 :     anyChars.ungetToken();
    8238             : 
    8239             :     // Save the tokenizer state in case we find an arrow function and have to
    8240             :     // rewind.
    8241      112585 :     Position start(keepAtoms, tokenStream);
    8242          19 : 
    8243             :     PossibleError possibleErrorInner(*this);
    8244             :     Node lhs;
    8245          19 :     TokenKind tokenAfterLHS;
    8246           0 :     bool isArrow;
    8247           0 :     if (maybeAsyncArrow) {
    8248             :         tokenStream.consumeKnownToken(TokenKind::Async, TokenStream::Operand);
    8249             : 
    8250          38 :         TokenKind tokenAfterAsync;
    8251          19 :         if (!tokenStream.getToken(&tokenAfterAsync))
    8252           0 :             return null();
    8253             :         MOZ_ASSERT(TokenKindIsPossibleIdentifier(tokenAfterAsync));
    8254           0 : 
    8255             :         // Check yield validity here.
    8256          19 :         RootedPropertyName name(context, bindingIdentifier(yieldHandling));
    8257           0 :         if (!name)
    8258             :             return null();
    8259           0 : 
    8260             :         if (!tokenStream.peekTokenSameLine(&tokenAfterLHS))
    8261             :             return null();
    8262           0 :         if (tokenAfterLHS != TokenKind::Arrow) {
    8263             :             error(JSMSG_UNEXPECTED_TOKEN,
    8264           0 :                   "'=>' on the same line after an argument list", TokenKindToDesc(tokenAfterLHS));
    8265      112568 :             return null();
    8266             :         }
    8267             : 
    8268             :         isArrow = true;
    8269             :     } else {
    8270             :         lhs = condExpr(inHandling, yieldHandling, tripledotHandling, &possibleErrorInner, invoked);
    8271           0 :         if (!lhs)
    8272             :             return null();
    8273             : 
    8274           0 :         // Use Operand here because the ConditionalExpression parsed above
    8275             :         // could be the entirety of this AssignmentExpression, and then ASI
    8276             :         // permits this token to be a regular expression.
    8277           0 :         if (!tokenStream.peekTokenSameLine(&tokenAfterLHS, TokenStream::Operand))
    8278        2410 :             return null();
    8279             : 
    8280             :         isArrow = tokenAfterLHS == TokenKind::Arrow;
    8281        2410 :     }
    8282             : 
    8283           0 :     if (isArrow) {
    8284        2410 :         tokenStream.seek(start);
    8285             : 
    8286           0 :         TokenKind next;
    8287             :         if (!tokenStream.getToken(&next, TokenStream::Operand))
    8288        2410 :             return null();
    8289           0 :         uint32_t toStringStart = pos().begin;
    8290             :         anyChars.ungetToken();
    8291         115 : 
    8292         115 :         FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction;
    8293           0 : 
    8294             :         if (next == TokenKind::Async) {
    8295             :             tokenStream.consumeKnownToken(next, TokenStream::Operand);
    8296             : 
    8297             :             TokenKind nextSameLine = TokenKind::Eof;
    8298           0 :             if (!tokenStream.peekTokenSameLine(&nextSameLine))
    8299             :                 return null();
    8300             : 
    8301           0 :             // The AsyncArrowFunction production are
    8302             :             //   async [no LineTerminator here] AsyncArrowBindingIdentifier ...
    8303             :             //   async [no LineTerminator here] ArrowFormalParameters ...
    8304           0 :             if (TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine == TokenKind::Lp)
    8305           1 :                 asyncKind = FunctionAsyncKind::AsyncFunction;
    8306             :             else
    8307             :                 anyChars.ungetToken();
    8308        4820 :         }
    8309             : 
    8310           0 :         Node pn = handler.newArrowFunction(pos());
    8311             :         if (!pn)
    8312             :             return null();
    8313           0 : 
    8314             :         return functionDefinition(pn, toStringStart, inHandling, yieldHandling, nullptr,
    8315             :                                   FunctionSyntaxKind::Arrow, GeneratorKind::NotGenerator,
    8316           0 :                                   asyncKind);
    8317             :     }
    8318         320 : 
    8319          12 :     MOZ_ALWAYS_TRUE(tokenStream.getToken(&tokenAfterLHS, TokenStream::Operand));
    8320           0 : 
    8321           7 :     ParseNodeKind kind;
    8322           0 :     switch (tokenAfterLHS) {
    8323           0 :       case TokenKind::Assign:       kind = ParseNodeKind::Assign;       break;
    8324           1 :       case TokenKind::AddAssign:    kind = ParseNodeKind::AddAssign;    break;
    8325           0 :       case TokenKind::SubAssign:    kind = ParseNodeKind::SubAssign;    break;
    8326          12 :       case TokenKind::BitOrAssign:  kind = ParseNodeKind::BitOrAssign;  break;
    8327           5 :       case TokenKind::BitXorAssign: kind = ParseNodeKind::BitXorAssign; break;
    8328           0 :       case TokenKind::BitAndAssign: kind = ParseNodeKind::BitAndAssign; break;
    8329           0 :       case TokenKind::LshAssign:    kind = ParseNodeKind::LshAssign;    break;
    8330             :       case TokenKind::RshAssign:    kind = ParseNodeKind::RshAssign;    break;
    8331             :       case TokenKind::UrshAssign:   kind = ParseNodeKind::UrshAssign;   break;
    8332           0 :       case TokenKind::MulAssign:    kind = ParseNodeKind::MulAssign;    break;
    8333           0 :       case TokenKind::DivAssign:    kind = ParseNodeKind::DivAssign;    break;
    8334           0 :       case TokenKind::ModAssign:    kind = ParseNodeKind::ModAssign;    break;
    8335             :       case TokenKind::PowAssign:    kind = ParseNodeKind::PowAssign;    break;
    8336             : 
    8337           0 :       default:
    8338             :         MOZ_ASSERT(!anyChars.isCurrentTokenAssignment());
    8339             :         if (!possibleError) {
    8340           0 :             if (!possibleErrorInner.checkForExpressionError())
    8341           0 :                 return null();
    8342             :         } else {
    8343             :             possibleErrorInner.transferErrorsTo(possibleError);
    8344             :         }
    8345           0 : 
    8346           0 :         anyChars.ungetToken();
    8347           0 :         return lhs;
    8348           0 :     }
    8349             : 
    8350             :     // Verify the left-hand side expression doesn't have a forbidden form.
    8351          29 :     if (handler.isUnparenthesizedDestructuringPattern(lhs)) {
    8352             :         if (kind != ParseNodeKind::Assign) {
    8353           0 :             error(JSMSG_BAD_DESTRUCT_ASS);
    8354        4071 :             return null();
    8355             :         }
    8356           0 : 
    8357             :         if (!possibleErrorInner.checkForDestructuringErrorOrWarning())
    8358             :             return null();
    8359             :     } else if (handler.isName(lhs)) {
    8360           0 :         if (const char* chars = nameIsArgumentsOrEval(lhs)) {
    8361        8095 :             // |chars| is "arguments" or "eval" here.
    8362             :             if (!strictModeErrorAt(exprPos.begin, JSMSG_BAD_STRICT_ASSIGN, chars))
    8363           0 :                 return null();
    8364           0 :         }
    8365             : 
    8366             :         handler.adjustGetToSet(lhs);
    8367           0 :     } else if (handler.isPropertyAccess(lhs)) {
    8368           0 :         // Permitted: no additional testing/fixup needed.
    8369             :     } else if (handler.isFunctionCall(lhs)) {
    8370           0 :         if (!strictModeErrorAt(exprPos.begin, JSMSG_BAD_LEFTSIDE_OF_ASS))
    8371           0 :             return null();
    8372             : 
    8373             :         if (possibleError)
    8374       12195 :             possibleError->setPendingDestructuringErrorAt(exprPos, JSMSG_BAD_DESTRUCT_TARGET);
    8375             :     } else {
    8376             :         errorAt(exprPos.begin, JSMSG_BAD_LEFTSIDE_OF_ASS);
    8377       12195 :         return null();
    8378       12195 :     }
    8379             : 
    8380             :     if (!possibleErrorInner.checkForExpressionError())
    8381       12195 :         return null();
    8382             : 
    8383             :     Node rhs = assignExpr(inHandling, yieldHandling, TripledotProhibited);
    8384             :     if (!rhs)
    8385             :         return null();
    8386           0 : 
    8387             :     return handler.newAssignment(kind, lhs, rhs);
    8388             : }
    8389             : 
    8390             : template <class ParseHandler>
    8391             : bool
    8392             : PerHandlerParser<ParseHandler>::isValidSimpleAssignmentTarget(Node node,
    8393           0 :                                                               FunctionCallBehavior behavior /* = ForbidAssignmentToFunctionCalls */)
    8394        3506 : {
    8395             :     // Note that this method implements *only* a boolean test.  Reporting an
    8396             :     // error for the various syntaxes that fail this, and warning for the
    8397        1459 :     // various syntaxes that "pass" this but should not, occurs elsewhere.
    8398             : 
    8399             :     if (handler.isName(node)) {
    8400         397 :         if (!pc->sc()->strict())
    8401             :             return true;
    8402             : 
    8403           0 :         return !nameIsArgumentsOrEval(node);
    8404           0 :     }
    8405             : 
    8406             :     if (handler.isPropertyAccess(node))
    8407             :         return true;
    8408             : 
    8409             :     if (behavior == PermitAssignmentToFunctionCalls) {
    8410             :         if (handler.isFunctionCall(node))
    8411             :             return true;
    8412             :     }
    8413        6063 : 
    8414             :     return false;
    8415           0 : }
    8416             : 
    8417        6063 : template <class ParseHandler>
    8418             : const char*
    8419        6063 : PerHandlerParser<ParseHandler>::nameIsArgumentsOrEval(Node node)
    8420             : {
    8421        6063 :     MOZ_ASSERT(handler.isName(node), "must only call this function on known names");
    8422             : 
    8423             :     if (handler.isEvalName(node, context))
    8424             :         return js_eval_str;
    8425             :     if (handler.isArgumentsName(node, context))
    8426         650 :         return js_arguments_str;
    8427             :     return nullptr;
    8428        1300 : }
    8429           0 : 
    8430           0 : template <class ParseHandler, typename CharT>
    8431             : bool
    8432             : GeneralParser<ParseHandler, CharT>::checkIncDecOperand(Node operand, uint32_t operandOffset)
    8433           0 : {
    8434             :     if (handler.isName(operand)) {
    8435           0 :         if (const char* chars = nameIsArgumentsOrEval(operand)) {
    8436             :             if (!strictModeErrorAt(operandOffset, JSMSG_BAD_STRICT_ASSIGN, chars))
    8437             :                 return false;
    8438             :         }
    8439             :     } else if (handler.isPropertyAccess(operand)) {
    8440           0 :         // Permitted: no additional testing/fixup needed.
    8441             :     } else if (handler.isFunctionCall(operand)) {
    8442             :         // Assignment to function calls is forbidden in ES6.  We're still
    8443           0 :         // somewhat concerned about sites using this in dead code, so forbid it
    8444           0 :         // only in strict mode code (or if the werror option has been set), and
    8445             :         // otherwise warn.
    8446             :         if (!strictModeErrorAt(operandOffset, JSMSG_BAD_INCOP_OPERAND))
    8447           0 :             return false;
    8448             :     } else {
    8449             :         errorAt(operandOffset, JSMSG_BAD_INCOP_OPERAND);
    8450             :         return false;
    8451             :     }
    8452             : 
    8453             :     MOZ_ASSERT(isValidSimpleAssignmentTarget(operand, PermitAssignmentToFunctionCalls),
    8454        5554 :                "inconsistent increment/decrement operand validation");
    8455             :     return true;
    8456             : }
    8457        5554 : 
    8458        5554 : template <class ParseHandler, typename CharT>
    8459             : typename ParseHandler::Node
    8460       11108 : GeneralParser<ParseHandler, CharT>::unaryOpExpr(YieldHandling yieldHandling, ParseNodeKind kind,
    8461             :                                                 uint32_t begin)
    8462             : {
    8463             :     Node kid = unaryExpr(yieldHandling, TripledotProhibited);
    8464             :     if (!kid)
    8465      140409 :         return null();
    8466             :     return handler.newUnary(kind, begin, kid);
    8467             : }
    8468             : 
    8469             : template <class ParseHandler, typename CharT>
    8470           0 : typename ParseHandler::Node
    8471             : GeneralParser<ParseHandler, CharT>::unaryExpr(YieldHandling yieldHandling,
    8472             :                                               TripledotHandling tripledotHandling,
    8473             :                                               PossibleError* possibleError /* = nullptr */,
    8474      140408 :                                               InvokedPrediction invoked /* = PredictUninvoked */)
    8475             : {
    8476      280812 :     if (!CheckRecursionLimit(context))
    8477           0 :         return null();
    8478             : 
    8479          26 :     TokenKind tt;
    8480             :     if (!tokenStream.getToken(&tt, TokenStream::Operand))
    8481        5070 :         return null();
    8482             :     uint32_t begin = pos().begin;
    8483          10 :     switch (tt) {
    8484             :       case TokenKind::Void:
    8485          15 :         return unaryOpExpr(yieldHandling, ParseNodeKind::Void, begin);
    8486             :       case TokenKind::Not:
    8487         433 :         return unaryOpExpr(yieldHandling, ParseNodeKind::Not, begin);
    8488             :       case TokenKind::BitNot:
    8489             :         return unaryOpExpr(yieldHandling, ParseNodeKind::BitNot, begin);
    8490             :       case TokenKind::Add:
    8491             :         return unaryOpExpr(yieldHandling, ParseNodeKind::Pos, begin);
    8492             :       case TokenKind::Sub:
    8493             :         return unaryOpExpr(yieldHandling, ParseNodeKind::Neg, begin);
    8494             : 
    8495             :       case TokenKind::TypeOf: {
    8496             :         // The |typeof| operator is specially parsed to distinguish its
    8497             :         // application to a name, from its application to a non-name
    8498             :         // expression:
    8499             :         //
    8500             :         //   // Looks up the name, doesn't find it and so evaluates to
    8501         721 :         //   // "undefined".
    8502         721 :         //   assertEq(typeof nonExistentName, "undefined");
    8503             :         //
    8504             :         //   // Evaluates expression, triggering a runtime ReferenceError for
    8505         721 :         //   // the undefined name.
    8506             :         //   typeof (1, nonExistentName);
    8507             :         Node kid = unaryExpr(yieldHandling, TripledotProhibited);
    8508             :         if (!kid)
    8509             :             return null();
    8510             : 
    8511             :         return handler.newTypeof(begin, kid);
    8512         138 :       }
    8513             : 
    8514             :       case TokenKind::Inc:
    8515         276 :       case TokenKind::Dec:
    8516             :       {
    8517           0 :         TokenKind tt2;
    8518         138 :         if (!tokenStream.getToken(&tt2, TokenStream::Operand))
    8519             :             return null();
    8520         138 : 
    8521             :         uint32_t operandOffset = pos().begin;
    8522         138 :         Node operand =
    8523         276 :             memberExpr(yieldHandling, TripledotProhibited, tt2);
    8524             :         if (!operand || !checkIncDecOperand(operand, operandOffset))
    8525             :             return null();
    8526             :         ParseNodeKind pnk = (tt == TokenKind::Inc)
    8527             :                             ? ParseNodeKind::PreIncrement
    8528         720 :                             : ParseNodeKind::PreDecrement;
    8529             :         return handler.newUpdate(pnk, begin, operand);
    8530             :       }
    8531         360 : 
    8532           0 :       case TokenKind::Delete: {
    8533             :         uint32_t exprOffset;
    8534             :         if (!tokenStream.peekOffset(&exprOffset, TokenStream::Operand))
    8535             :             return null();
    8536             : 
    8537         720 :         Node expr = unaryExpr(yieldHandling, TripledotProhibited);
    8538           0 :         if (!expr)
    8539             :             return null();
    8540             : 
    8541           0 :         // Per spec, deleting any unary expression is valid -- it simply
    8542             :         // returns true -- except for one case that is illegal in strict mode.
    8543             :         if (handler.isName(expr)) {
    8544           0 :             if (!strictModeErrorAt(exprOffset, JSMSG_DEPRECATED_DELETE_OPERAND))
    8545             :                 return null();
    8546             : 
    8547             :             pc->sc()->setBindingsAccessedDynamically();
    8548        2444 :         }
    8549           0 : 
    8550           0 :         return handler.newDelete(begin, expr);
    8551             :       }
    8552        1222 : 
    8553           0 :       case TokenKind::Await: {
    8554             :         if (pc->isAsync()) {
    8555             :             Node kid = unaryExpr(yieldHandling, tripledotHandling, possibleError, invoked);
    8556             :             if (!kid)
    8557             :                 return null();
    8558             :             pc->lastAwaitOffset = begin;
    8559             :             return handler.newAwaitExpression(begin, kid);
    8560           0 :         }
    8561           0 :       }
    8562           0 : 
    8563             :         MOZ_FALLTHROUGH;
    8564             : 
    8565             :       default: {
    8566      132415 :         Node expr = memberExpr(yieldHandling, tripledotHandling, tt,
    8567             :                                /* allowCallSyntax = */ true, possibleError, invoked);
    8568             :         if (!expr)
    8569      132415 :             return null();
    8570             : 
    8571             :         /* Don't look across a newline boundary for a postfix incop. */
    8572           0 :         if (!tokenStream.peekTokenSameLine(&tt))
    8573           0 :             return null();
    8574             : 
    8575             :         if (tt != TokenKind::Inc && tt != TokenKind::Dec)
    8576         512 :             return expr;
    8577             : 
    8578           0 :         tokenStream.consumeKnownToken(tt);
    8579        1024 :         if (!checkIncDecOperand(expr, begin))
    8580             :             return null();
    8581             : 
    8582             :         ParseNodeKind pnk = (tt == TokenKind::Inc)
    8583             :                             ? ParseNodeKind::PostIncrement
    8584             :                             : ParseNodeKind::PostDecrement;
    8585             :         return handler.newUpdate(pnk, begin, expr);
    8586             :       }
    8587         545 :     }
    8588             : }
    8589         545 : 
    8590           0 : 
    8591           0 : template <class ParseHandler, typename CharT>
    8592         545 : typename ParseHandler::Node
    8593         545 : GeneralParser<ParseHandler, CharT>::assignExprWithoutYieldOrAwait(YieldHandling yieldHandling)
    8594           0 : {
    8595           0 :     uint32_t startYieldOffset = pc->lastYieldOffset;
    8596             :     uint32_t startAwaitOffset = pc->lastAwaitOffset;
    8597         545 :     Node res = assignExpr(InAllowed, yieldHandling, TripledotProhibited);
    8598           0 :     if (res) {
    8599           0 :         if (pc->lastYieldOffset != startYieldOffset) {
    8600             :             errorAt(pc->lastYieldOffset, JSMSG_YIELD_IN_DEFAULT);
    8601             :             return null();
    8602             :         }
    8603             :         if (pc->lastAwaitOffset != startAwaitOffset) {
    8604             :             errorAt(pc->lastAwaitOffset, JSMSG_AWAIT_IN_DEFAULT);
    8605             :             return null();
    8606             :         }
    8607           0 :     }
    8608             :     return res;
    8609             : }
    8610             : 
    8611             : template <class ParseHandler, typename CharT>
    8612       43975 : bool
    8613             : GeneralParser<ParseHandler, CharT>::argumentList(YieldHandling yieldHandling, Node listNode,
    8614       43975 :                                                  bool* isSpread,
    8615       12402 :                                                  PossibleError* possibleError /* = nullptr */)
    8616        6201 : {
    8617             :     bool matched;
    8618             :     if (!tokenStream.matchToken(&matched, TokenKind::Rp, TokenStream::Operand))
    8619           0 :         return false;
    8620       61098 :     if (matched) {
    8621       61098 :         handler.setEndPosition(listNode, pos().end);
    8622       61098 :         return true;
    8623           0 :     }
    8624           0 : 
    8625         138 :     while (true) {
    8626           0 :         bool spread = false;
    8627           0 :         uint32_t begin = 0;
    8628             :         if (!tokenStream.matchToken(&matched, TokenKind::TripleDot, TokenStream::Operand))
    8629             :             return false;
    8630       61097 :         if (matched) {
    8631           0 :             spread = true;
    8632             :             begin = pos().begin;
    8633           0 :             *isSpread = true;
    8634           0 :         }
    8635           0 : 
    8636             :         Node argNode = assignExpr(InAllowed, yieldHandling, TripledotProhibited, possibleError);
    8637             :         if (!argNode)
    8638             :             return false;
    8639           0 :         if (spread) {
    8640             :             argNode = handler.newSpread(begin, argNode);
    8641             :             if (!argNode)
    8642           0 :                 return false;
    8643             :         }
    8644       61098 : 
    8645             :         handler.addList(listNode, argNode);
    8646             : 
    8647             :         bool matched;
    8648       23332 :         if (!tokenStream.matchToken(&matched, TokenKind::Comma, TokenStream::Operand))
    8649             :             return false;
    8650       23332 :         if (!matched)
    8651             :             break;
    8652             : 
    8653             :         TokenKind tt;
    8654           0 :         if (!tokenStream.peekToken(&tt, TokenStream::Operand))
    8655             :             return null();
    8656           0 :         if (tt == TokenKind::Rp)
    8657       37774 :             break;
    8658             :     }
    8659             : 
    8660             :     MUST_MATCH_TOKEN_MOD(TokenKind::Rp, TokenStream::Operand, JSMSG_PAREN_AFTER_ARGS);
    8661           0 : 
    8662             :     handler.setEndPosition(listNode, pos().end);
    8663         160 :     return true;
    8664             : }
    8665             : 
    8666           0 : bool
    8667           0 : ParserBase::checkAndMarkSuperScope()
    8668             : {
    8669             :     if (!pc->sc()->allowSuperProperty())
    8670             :         return false;
    8671             : 
    8672      135544 :     pc->setSuperScopeNeedsHomeObject();
    8673             :     return true;
    8674             : }
    8675             : 
    8676             : template <class ParseHandler, typename CharT>
    8677             : typename ParseHandler::Node
    8678           0 : GeneralParser<ParseHandler, CharT>::memberExpr(YieldHandling yieldHandling,
    8679             :                                                TripledotHandling tripledotHandling,
    8680             :                                                TokenKind tt, bool allowCallSyntax /* = true */,
    8681             :                                                PossibleError* possibleError /* = nullptr */,
    8682      135544 :                                                InvokedPrediction invoked /* = PredictUninvoked */)
    8683             : {
    8684             :     MOZ_ASSERT(anyChars.isCurrentTokenType(tt));
    8685             : 
    8686      135543 :     Node lhs;
    8687        5762 : 
    8688             :     if (!CheckRecursionLimit(context))
    8689             :         return null();
    8690           0 : 
    8691           0 :     /* Check for new expression first. */
    8692        2881 :     if (tt == TokenKind::New) {
    8693             :         uint32_t newBegin = pos().begin;
    8694             :         // Make sure this wasn't a |new.target| in disguise.
    8695             :         Node newTarget;
    8696        5754 :         if (!tryNewTarget(newTarget))
    8697             :             return null();
    8698             :         if (newTarget) {
    8699           0 :             lhs = newTarget;
    8700        2877 :         } else {
    8701           0 :             // Gotten by tryNewTarget
    8702             :             tt = anyChars.currentToken().type;
    8703           0 :             Node ctorExpr = memberExpr(yieldHandling, TripledotProhibited, tt,
    8704           0 :                                        /* allowCallSyntax = */ false,
    8705             :                                        /* possibleError = */ nullptr, PredictInvoked);
    8706             :             if (!ctorExpr)
    8707             :                 return null();
    8708           0 : 
    8709             :             lhs = handler.newNewExpression(newBegin, ctorExpr);
    8710        2877 :             if (!lhs)
    8711           0 :                 return null();
    8712           0 : 
    8713           0 :             bool matched;
    8714        2867 :             if (!tokenStream.matchToken(&matched, TokenKind::Lp))
    8715           0 :                 return null();
    8716             :             if (matched) {
    8717             :                 bool isSpread = false;
    8718      132662 :                 if (!argumentList(yieldHandling, lhs, &isSpread))
    8719         139 :                     return null();
    8720           0 :                 if (isSpread)
    8721             :                     handler.setOp(lhs, JSOP_SPREADNEW);
    8722           0 :             }
    8723           0 :         }
    8724             :     } else if (tt == TokenKind::Super) {
    8725           0 :         Node thisName = newThisName();
    8726           0 :         if (!thisName)
    8727           0 :             return null();
    8728             :         lhs = handler.newSuperBase(thisName, pos());
    8729             :         if (!lhs)
    8730           0 :             return null();
    8731           0 :     } else if (tt == TokenKind::Import) {
    8732             :         lhs = importMeta();
    8733             :         if (!lhs)
    8734             :             return null();
    8735           0 :     } else {
    8736             :         lhs = primaryExpr(yieldHandling, tripledotHandling, tt, possibleError, invoked);
    8737             :         if (!lhs)
    8738           0 :             return null();
    8739             :     }
    8740      264340 : 
    8741             :     MOZ_ASSERT_IF(handler.isSuperBase(lhs), anyChars.isCurrentTokenType(TokenKind::Super));
    8742             : 
    8743             :     while (true) {
    8744      264270 :         if (!tokenStream.getToken(&tt))
    8745       84008 :             return null();
    8746             :         if (tt == TokenKind::Eof)
    8747           0 :             break;
    8748       84010 : 
    8749      168080 :         Node nextMember;
    8750           0 :         if (tt == TokenKind::Dot) {
    8751           0 :             if (!tokenStream.getToken(&tt))
    8752             :                 return null();
    8753      252030 :             if (TokenKindIsPossibleIdentifierName(tt)) {
    8754       84010 :                 PropertyName* field = anyChars.currentName();
    8755             :                 if (handler.isSuperBase(lhs) && !checkAndMarkSuperScope()) {
    8756             :                     error(JSMSG_BAD_SUPERPROP, "property");
    8757           0 :                     return null();
    8758           0 :                 }
    8759             :                 nextMember = handler.newPropertyAccess(lhs, field, pos().end);
    8760           0 :                 if (!nextMember)
    8761           0 :                     return null();
    8762           0 :             } else {
    8763             :                 error(JSMSG_NAME_AFTER_DOT);
    8764             :                 return null();
    8765           0 :             }
    8766             :         } else if (tt == TokenKind::Lb) {
    8767        7352 :             Node propExpr = expr(InAllowed, yieldHandling, TripledotProhibited);
    8768           0 :             if (!propExpr)
    8769           0 :                 return null();
    8770             : 
    8771       11028 :             MUST_MATCH_TOKEN_MOD(TokenKind::Rb, TokenStream::Operand, JSMSG_BRACKET_IN_INDEX);
    8772           0 : 
    8773             :             if (handler.isSuperBase(lhs) && !checkAndMarkSuperScope()) {
    8774           0 :                 error(JSMSG_BAD_SUPERPROP, "member");
    8775      135476 :                 return null();
    8776             :             }
    8777             :             nextMember = handler.newPropertyByValue(lhs, propExpr, pos().end);
    8778       82230 :             if (!nextMember)
    8779           0 :                 return null();
    8780           0 :         } else if ((allowCallSyntax && tt == TokenKind::Lp) ||
    8781           0 :                    tt == TokenKind::TemplateHead ||
    8782             :                    tt == TokenKind::NoSubsTemplate)
    8783             :         {
    8784           0 :             if (handler.isSuperBase(lhs)) {
    8785           0 :                 if (!pc->sc()->allowSuperCall()) {
    8786           0 :                     error(JSMSG_BAD_SUPERCALL);
    8787             :                     return null();
    8788             :                 }
    8789         158 : 
    8790           0 :                 if (tt != TokenKind::Lp) {
    8791             :                     error(JSMSG_BAD_SUPER);
    8792             :                     return null();
    8793             :                 }
    8794             : 
    8795             :                 nextMember = handler.newSuperCall(lhs);
    8796           0 :                 if (!nextMember)
    8797           1 :                     return null();
    8798             : 
    8799             :                 // Despite the fact that it's impossible to have |super()| in a
    8800          79 :                 // generator, we still inherit the yieldHandling of the
    8801           0 :                 // memberExpression, per spec. Curious.
    8802             :                 bool isSpread = false;
    8803          79 :                 if (!argumentList(yieldHandling, nextMember, &isSpread))
    8804          79 :                     return null();
    8805             : 
    8806             :                 if (isSpread)
    8807          79 :                     handler.setOp(nextMember, JSOP_SPREADSUPERCALL);
    8808           0 : 
    8809             :                 Node thisName = newThisName();
    8810             :                 if (!thisName)
    8811       82072 :                     return null();
    8812           0 : 
    8813           0 :                 nextMember = handler.newSetThis(thisName, nextMember);
    8814             :                 if (!nextMember)
    8815             :                     return null();
    8816           0 :             } else {
    8817       82072 :                 if (options().selfHostingMode && handler.isPropertyAccess(lhs)) {
    8818       82072 :                     error(JSMSG_SELFHOSTED_METHOD_CALL);
    8819             :                     return null();
    8820           0 :                 }
    8821             : 
    8822             :                 TokenPos nextMemberPos = pos();
    8823           0 :                 nextMember = tt == TokenKind::Lp
    8824           1 :                              ? handler.newCall(nextMemberPos)
    8825           1 :                              : handler.newTaggedTemplate(nextMemberPos);
    8826             :                 if (!nextMember)
    8827             :                     return null();
    8828           0 : 
    8829           0 :                 JSOp op = JSOP_CALL;
    8830           0 :                 bool maybeAsyncArrow = false;
    8831         118 :                 if (PropertyName* prop = handler.maybeDottedProperty(lhs)) {
    8832           0 :                     // Use the JSOP_FUN{APPLY,CALL} optimizations given the
    8833         127 :                     // right syntax.
    8834             :                     if (prop == context->names().apply) {
    8835           0 :                         op = JSOP_FUNAPPLY;
    8836           0 :                         if (pc->isFunctionBox())
    8837             :                             pc->functionBox()->usesApply = true;
    8838             :                     } else if (prop == context->names().call) {
    8839             :                         op = JSOP_FUNCALL;
    8840             :                     }
    8841             :                 } else if (tt == TokenKind::Lp) {
    8842             :                     if (handler.isAsyncKeyword(lhs, context)) {
    8843             :                         // |async (| can be the start of an async arrow
    8844           0 :                         // function, so we need to defer reporting possible
    8845             :                         // errors from destructuring syntax. To give better
    8846             :                         // error messages, we only allow the AsyncArrowHead
    8847           0 :                         // part of the CoverCallExpressionAndAsyncArrowHead
    8848           0 :                         // syntax when the initial name is "async".
    8849          40 :                         maybeAsyncArrow = true;
    8850             :                     } else if (handler.isEvalName(lhs, context)) {
    8851             :                         // Select the right EVAL op and flag pc as having a
    8852             :                         // direct eval.
    8853          60 :                         op = pc->sc()->strict() ? JSOP_STRICTEVAL : JSOP_EVAL;
    8854          40 :                         pc->sc()->setBindingsAccessedDynamically();
    8855             :                         pc->sc()->setHasDirectEval();
    8856             : 
    8857             :                         // In non-strict mode code, direct calls to eval can
    8858             :                         // add variables to the call object.
    8859             :                         if (pc->isFunctionBox() && !pc->sc()->strict())
    8860           0 :                             pc->functionBox()->setHasExtensibleScope();
    8861             : 
    8862             :                         // If we're in a method, mark the method as requiring
    8863             :                         // support for 'super', since direct eval code can use
    8864       82072 :                         // it. (If we're not in a method, that's fine, so
    8865           0 :                         // ignore the return value.)
    8866             :                         checkAndMarkSuperScope();
    8867       41036 :                     }
    8868       41029 :                 }
    8869       41029 : 
    8870       41029 :                 handler.setBeginPosition(nextMember, lhs);
    8871           0 :                 handler.addList(nextMember, lhs);
    8872           0 : 
    8873         133 :                 if (tt == TokenKind::Lp) {
    8874             :                     bool isSpread = false;
    8875         133 :                     PossibleError* asyncPossibleError = maybeAsyncArrow ? possibleError : nullptr;
    8876             :                     if (!argumentList(yieldHandling, nextMember, &isSpread, asyncPossibleError))
    8877             :                         return null();
    8878         133 :                     if (isSpread) {
    8879             :                         if (op == JSOP_EVAL)
    8880             :                             op = JSOP_SPREADEVAL;
    8881           0 :                         else if (op == JSOP_STRICTEVAL)
    8882             :                             op = JSOP_STRICTSPREADEVAL;
    8883             :                         else
    8884           0 :                             op = JSOP_SPREADCALL;
    8885             :                     }
    8886             :                 } else {
    8887           0 :                     if (!taggedTemplate(yieldHandling, nextMember, tt))
    8888      270942 :                         return null();
    8889             :                 }
    8890             :                 handler.setOp(nextMember, op);
    8891             :             }
    8892             :         } else {
    8893             :             anyChars.ungetToken();
    8894             :             if (handler.isSuperBase(lhs))
    8895             :                 break;
    8896           0 :             return lhs;
    8897           0 :         }
    8898           0 : 
    8899             :         lhs = nextMember;
    8900             :     }
    8901             : 
    8902             :     if (handler.isSuperBase(lhs)) {
    8903             :         error(JSMSG_BAD_SUPER);
    8904             :         return null();
    8905             :     }
    8906      169096 : 
    8907             :     return lhs;
    8908           0 : }
    8909             : 
    8910             : template <class ParseHandler>
    8911             : inline typename ParseHandler::Node
    8912             : PerHandlerParser<ParseHandler>::newName(PropertyName* name)
    8913           0 : {
    8914             :     return newName(name, pos());
    8915      338906 : }
    8916             : 
    8917             : template <class ParseHandler>
    8918             : inline typename ParseHandler::Node
    8919             : PerHandlerParser<ParseHandler>::newName(PropertyName* name, TokenPos pos)
    8920           0 : {
    8921             :     return handler.newName(name, pos, context);
    8922             : }
    8923             : 
    8924             : template <class ParseHandler, typename CharT>
    8925             : bool
    8926      148447 : GeneralParser<ParseHandler, CharT>::checkLabelOrIdentifierReference(PropertyName* ident,
    8927           0 :                                                                     uint32_t offset,
    8928             :                                                                     YieldHandling yieldHandling,
    8929      148447 :                                                                     TokenKind hint /* = TokenKind::Limit */)
    8930             : {
    8931             :     TokenKind tt;
    8932             :     if (hint == TokenKind::Limit) {
    8933      148446 :         tt = ReservedWordTokenKind(ident);
    8934             :     } else {
    8935         670 :         MOZ_ASSERT(hint == ReservedWordTokenKind(ident), "hint doesn't match actual token kind");
    8936         670 :         tt = hint;
    8937           0 :     }
    8938           0 : 
    8939           0 :     if (tt == TokenKind::Name)
    8940             :         return true;
    8941           0 :     if (TokenKindIsContextualKeyword(tt)) {
    8942           0 :         if (tt == TokenKind::Yield) {
    8943             :             if (yieldHandling == YieldIsKeyword) {
    8944             :                 errorAt(offset, JSMSG_RESERVED_ID, "yield");
    8945             :                 return false;
    8946             :             }
    8947           0 :             if (pc->sc()->needStrictChecks()) {
    8948           0 :                 if (!strictModeErrorAt(offset, JSMSG_RESERVED_ID, "yield"))
    8949           0 :                     return false;
    8950           0 :             }
    8951             :             return true;
    8952             :         }
    8953             :         if (tt == TokenKind::Await) {
    8954           0 :             if (awaitIsKeyword()) {
    8955         572 :                 errorAt(offset, JSMSG_RESERVED_ID, "await");
    8956           0 :                 return false;
    8957             :             }
    8958           0 :             return true;
    8959             :         }
    8960           0 :         if (pc->sc()->needStrictChecks()) {
    8961           0 :             if (tt == TokenKind::Let) {
    8962             :                 if (!strictModeErrorAt(offset, JSMSG_RESERVED_ID, "let"))
    8963           0 :                     return false;
    8964             :                 return true;
    8965             :             }
    8966             :             if (tt == TokenKind::Static) {
    8967             :                 if (!strictModeErrorAt(offset, JSMSG_RESERVED_ID, "static"))
    8968           0 :                     return false;
    8969           0 :                 return true;
    8970           0 :             }
    8971             :         }
    8972             :         return true;
    8973             :     }
    8974             :     if (TokenKindIsStrictReservedWord(tt)) {
    8975           0 :         if (pc->sc()->needStrictChecks()) {
    8976           0 :             if (!strictModeErrorAt(offset, JSMSG_RESERVED_ID, ReservedWordToCharZ(tt)))
    8977           0 :                 return false;
    8978             :         }
    8979           0 :         return true;
    8980           0 :     }
    8981           0 :     if (TokenKindIsKeyword(tt) || TokenKindIsReservedWordLiteral(tt)) {
    8982             :         errorAt(offset, JSMSG_INVALID_ID, ReservedWordToCharZ(tt));
    8983           0 :         return false;
    8984             :     }
    8985             :     if (TokenKindIsFutureReservedWord(tt)) {
    8986             :         errorAt(offset, JSMSG_RESERVED_ID, ReservedWordToCharZ(tt));
    8987             :         return false;
    8988             :     }
    8989           0 :     MOZ_ASSERT_UNREACHABLE("Unexpected reserved word kind.");
    8990             :     return false;
    8991             : }
    8992             : 
    8993           0 : template <class ParseHandler, typename CharT>
    8994       86607 : bool
    8995           0 : GeneralParser<ParseHandler, CharT>::checkBindingIdentifier(PropertyName* ident, uint32_t offset,
    8996             :                                                            YieldHandling yieldHandling,
    8997           0 :                                                            TokenKind hint /* = TokenKind::Limit */)
    8998             : {
    8999             :     if (pc->sc()->needStrictChecks()) {
    9000       86607 :         if (ident == context->names().arguments) {
    9001           0 :             if (!strictModeErrorAt(offset, JSMSG_BAD_STRICT_ASSIGN, "arguments"))
    9002             :                 return false;
    9003           0 :             return true;
    9004             :         }
    9005             : 
    9006             :         if (ident == context->names().eval) {
    9007           0 :             if (!strictModeErrorAt(offset, JSMSG_BAD_STRICT_ASSIGN, "eval"))
    9008             :                 return false;
    9009             :             return true;
    9010             :         }
    9011             :     }
    9012           0 : 
    9013             :     return checkLabelOrIdentifierReference(ident, offset, yieldHandling, hint);
    9014             : }
    9015             : 
    9016             : template <class ParseHandler, typename CharT>
    9017             : PropertyName*
    9018             : GeneralParser<ParseHandler, CharT>::labelOrIdentifierReference(YieldHandling yieldHandling)
    9019             : {
    9020             :     // ES 2017 draft 12.1.1.
    9021             :     //   StringValue of IdentifierName normalizes any Unicode escape sequences
    9022             :     //   in IdentifierName hence such escapes cannot be used to write an
    9023      112991 :     //   Identifier whose code point sequence is the same as a ReservedWord.
    9024           0 :     //
    9025      112991 :     // Use PropertyName* instead of TokenKind to reflect the normalization.
    9026      225984 : 
    9027      338982 :     // Unless the name contains escapes, we can reuse the current TokenKind
    9028             :     // to determine if the name is a restricted identifier.
    9029      112993 :     TokenKind hint = !anyChars.currentNameHasEscapes()
    9030             :                      ? anyChars.currentToken().type
    9031             :                      : TokenKind::Limit;
    9032             :     RootedPropertyName ident(context, anyChars.currentName());
    9033             :     if (!checkLabelOrIdentifierReference(ident, pos().begin, yieldHandling, hint))
    9034       35457 :         return nullptr;
    9035             :     return ident;
    9036           0 : }
    9037           0 : 
    9038           0 : template <class ParseHandler, typename CharT>
    9039           0 : PropertyName*
    9040      106374 : GeneralParser<ParseHandler, CharT>::bindingIdentifier(YieldHandling yieldHandling)
    9041             : {
    9042       35458 :     TokenKind hint = !anyChars.currentNameHasEscapes()
    9043             :                      ? anyChars.currentToken().type
    9044             :                      : TokenKind::Limit;
    9045             :     RootedPropertyName ident(context, anyChars.currentName());
    9046             :     if (!checkBindingIdentifier(ident, pos().begin, yieldHandling, hint))
    9047      112993 :         return nullptr;
    9048             :     return ident;
    9049           0 : }
    9050           0 : 
    9051             : template <class ParseHandler>
    9052             : typename ParseHandler::Node
    9053      112992 : PerHandlerParser<ParseHandler>::identifierReference(Handle<PropertyName*> name)
    9054             : {
    9055             :     Node pn = newName(name);
    9056      112992 :     if (!pn)
    9057             :         return null();
    9058             : 
    9059             :     if (!noteUsedName(name))
    9060             :         return null();
    9061           0 : 
    9062             :     return pn;
    9063      120460 : }
    9064             : 
    9065             : template <class ParseHandler>
    9066             : typename ParseHandler::Node
    9067             : PerHandlerParser<ParseHandler>::stringLiteral()
    9068           0 : {
    9069             :     return handler.newStringLiteral(anyChars.currentToken().atom(), pos());
    9070          13 : }
    9071           0 : 
    9072           0 : template <class ParseHandler>
    9073             : typename ParseHandler::Node
    9074             : PerHandlerParser<ParseHandler>::noSubstitutionTaggedTemplate()
    9075           0 : {
    9076             :     if (anyChars.hasInvalidTemplateEscape()) {
    9077             :         anyChars.clearInvalidTemplateEscape();
    9078             :         return handler.newRawUndefinedLiteral(pos());
    9079             :     }
    9080           0 : 
    9081             :     return handler.newTemplateStringLiteral(anyChars.currentToken().atom(), pos());
    9082           0 : }
    9083             : 
    9084             : template <class ParseHandler, typename CharT>
    9085        8112 : typename ParseHandler::Node
    9086             : GeneralParser<ParseHandler, CharT>::noSubstitutionUntaggedTemplate()
    9087             : {
    9088             :     if (!tokenStream.checkForInvalidTemplateEscapeError())
    9089             :         return null();
    9090         298 : 
    9091             :     return handler.newTemplateStringLiteral(anyChars.currentToken().atom(), pos());
    9092           0 : }
    9093             : 
    9094             : template <typename CharT>
    9095             : ParseNode*
    9096             : Parser<FullParseHandler, CharT>::newRegExp()
    9097             : {
    9098         596 :     MOZ_ASSERT(!options().selfHostingMode);
    9099         298 : 
    9100         596 :     static_assert(mozilla::IsSame<CharT, char16_t>::value,
    9101             :                   "code below will need changing for UTF-8 handling");
    9102           0 : 
    9103         596 :     // Create the regexp and check its syntax.
    9104           0 :     const CharT* chars = tokenStream.getTokenbuf().begin();
    9105             :     size_t length = tokenStream.getTokenbuf().length();
    9106             :     RegExpFlag flags = anyChars.currentToken().regExpFlags();
    9107         894 : 
    9108             :     Rooted<RegExpObject*> reobj(context);
    9109             :     reobj = RegExpObject::create(context, chars, length, flags, anyChars, alloc, TenuredObject);
    9110             :     if (!reobj)
    9111             :         return null();
    9112           0 : 
    9113             :     return handler.newRegExp(reobj, pos(), *this);
    9114           0 : }
    9115             : 
    9116             : template <typename CharT>
    9117             : SyntaxParseHandler::Node
    9118             : Parser<SyntaxParseHandler, CharT>::newRegExp()
    9119             : {
    9120           0 :     MOZ_ASSERT(!options().selfHostingMode);
    9121           0 : 
    9122           0 :     static_assert(mozilla::IsSame<CharT, char16_t>::value,
    9123             :                   "code below will need changing for UTF-8 handling");
    9124           0 : 
    9125           0 :     // Only check the regexp's syntax, but don't create a regexp object.
    9126             :     const CharT* chars = tokenStream.getTokenbuf().begin();
    9127             :     size_t length = tokenStream.getTokenbuf().length();
    9128           0 :     RegExpFlag flags = anyChars.currentToken().regExpFlags();
    9129             : 
    9130             :     mozilla::Range<const CharT> source(chars, length);
    9131             :     if (!js::irregexp::ParsePatternSyntax(anyChars, alloc, source, flags & UnicodeFlag))
    9132             :         return null();
    9133           0 : 
    9134             :     return handler.newRegExp(SyntaxParseHandler::NodeGeneric, pos(), *this);
    9135         298 : }
    9136             : 
    9137             : template <class ParseHandler, typename CharT>
    9138             : typename ParseHandler::Node
    9139             : GeneralParser<ParseHandler, CharT>::newRegExp()
    9140             : {
    9141             :     return asFinalParser()->newRegExp();
    9142       15970 : }
    9143             : 
    9144             : // |exprPossibleError| is the PossibleError state within |expr|,
    9145             : // |possibleError| is the surrounding PossibleError state.
    9146             : template <class ParseHandler, typename CharT>
    9147             : bool
    9148             : GeneralParser<ParseHandler, CharT>::checkDestructuringAssignmentTarget(Node expr, TokenPos exprPos,
    9149             :                                                                        PossibleError* exprPossibleError,
    9150       15970 :                                                                        PossibleError* possibleError,
    9151        1882 :                                                                        TargetBehavior behavior)
    9152             : {
    9153             :     // Report any pending expression error if we're definitely not in a
    9154             :     // destructuring context or the possible destructuring target is a
    9155             :     // property accessor.
    9156             :     if (!possibleError || handler.isPropertyAccess(expr))
    9157             :         return exprPossibleError->checkForExpressionError();
    9158       14088 : 
    9159             :     // |expr| may end up as a destructuring assignment target, so we need to
    9160             :     // validate it's either a name or can be parsed as a nested destructuring
    9161       14088 :     // pattern. Property accessors are also valid assignment targets, but
    9162             :     // those are already handled above.
    9163             : 
    9164       10080 :     exprPossibleError->transferErrorsTo(possibleError);
    9165        1470 : 
    9166        1470 :     // Return early if a pending destructuring error is already present.
    9167             :     if (possibleError->hasPendingDestructuringError())
    9168             :         return true;
    9169        3570 : 
    9170           0 :     if (handler.isName(expr)) {
    9171           0 :         checkDestructuringAssignmentName(expr, exprPos, possibleError);
    9172             :         return true;
    9173             :     }
    9174             : 
    9175             :     if (handler.isUnparenthesizedDestructuringPattern(expr)) {
    9176             :         if (behavior == TargetBehavior::ForbidAssignmentPattern)
    9177             :             possibleError->setPendingDestructuringErrorAt(exprPos, JSMSG_BAD_DESTRUCT_TARGET);
    9178           0 :         return true;
    9179             :     }
    9180             : 
    9181           0 :     // Parentheses are forbidden around destructuring *patterns* (but allowed
    9182             :     // around names). Use our nicer error message for parenthesized, nested
    9183           1 :     // patterns if nested destructuring patterns are allowed.
    9184             :     if (handler.isParenthesizedDestructuringPattern(expr) &&
    9185             :         behavior != TargetBehavior::ForbidAssignmentPattern)
    9186             :     {
    9187             :         possibleError->setPendingDestructuringErrorAt(exprPos, JSMSG_BAD_DESTRUCT_PARENS);
    9188             :     } else {
    9189             :         possibleError->setPendingDestructuringErrorAt(exprPos, JSMSG_BAD_DESTRUCT_TARGET);
    9190             :     }
    9191        2631 : 
    9192             :     return true;
    9193             : }
    9194             : 
    9195             : template <class ParseHandler, typename CharT>
    9196        5262 : void
    9197        2631 : GeneralParser<ParseHandler, CharT>::checkDestructuringAssignmentName(Node name, TokenPos namePos,
    9198             :                                                                      PossibleError* possibleError)
    9199             : {
    9200             : #ifdef DEBUG
    9201        2631 :     // GCC 8.0.1 crashes if this is a one-liner.
    9202             :     bool isName = handler.isName(name);
    9203             :     MOZ_ASSERT(isName);
    9204        4926 : #endif
    9205        2098 : 
    9206           0 :     // Return early if a pending destructuring error is already present.
    9207           0 :     if (possibleError->hasPendingDestructuringError())
    9208             :         return;
    9209             : 
    9210           0 :     if (pc->sc()->needStrictChecks()) {
    9211             :         if (handler.isArgumentsName(name, context)) {
    9212             :             if (pc->sc()->strict()) {
    9213             :                 possibleError->setPendingDestructuringErrorAt(namePos,
    9214             :                                                               JSMSG_BAD_STRICT_ASSIGN_ARGUMENTS);
    9215             :             } else {
    9216           0 :                 possibleError->setPendingDestructuringWarningAt(namePos,
    9217           0 :                                                                 JSMSG_BAD_STRICT_ASSIGN_ARGUMENTS);
    9218           0 :             }
    9219             :             return;
    9220             :         }
    9221           0 : 
    9222             :         if (handler.isEvalName(name, context)) {
    9223             :             if (pc->sc()->strict()) {
    9224             :                 possibleError->setPendingDestructuringErrorAt(namePos,
    9225             :                                                               JSMSG_BAD_STRICT_ASSIGN_EVAL);
    9226             :             } else {
    9227             :                 possibleError->setPendingDestructuringWarningAt(namePos,
    9228             :                                                                 JSMSG_BAD_STRICT_ASSIGN_EVAL);
    9229             :             }
    9230             :             return;
    9231       15851 :         }
    9232             :     }
    9233             : }
    9234             : 
    9235             : template <class ParseHandler, typename CharT>
    9236             : bool
    9237             : GeneralParser<ParseHandler, CharT>::checkDestructuringAssignmentElement(Node expr, TokenPos exprPos,
    9238             :                                                                         PossibleError* exprPossibleError,
    9239             :                                                                         PossibleError* possibleError)
    9240             : {
    9241             :     // ES2018 draft rev 0719f44aab93215ed9a626b2f45bd34f36916834
    9242             :     // 12.15.5 Destructuring Assignment
    9243             :     //
    9244             :     // AssignmentElement[Yield, Await]:
    9245       15851 :     //   DestructuringAssignmentTarget[?Yield, ?Await]
    9246             :     //   DestructuringAssignmentTarget[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]
    9247             : 
    9248           0 :     // If |expr| is an assignment element with an initializer expression, its
    9249           0 :     // destructuring assignment target was already validated in assignExpr().
    9250             :     // Otherwise we need to check that |expr| is a valid destructuring target.
    9251           0 :     if (handler.isUnparenthesizedAssignment(expr)) {
    9252           0 :         // Report any pending expression error if we're definitely not in a
    9253             :         // destructuring context.
    9254       15851 :         if (!possibleError)
    9255             :             return exprPossibleError->checkForExpressionError();
    9256             : 
    9257             :         exprPossibleError->transferErrorsTo(possibleError);
    9258             :         return true;
    9259        2752 :     }
    9260             :     return checkDestructuringAssignmentTarget(expr, exprPos, exprPossibleError, possibleError);
    9261             : }
    9262        5504 : 
    9263             : template <class ParseHandler, typename CharT>
    9264           0 : typename ParseHandler::Node
    9265        5504 : GeneralParser<ParseHandler, CharT>::arrayInitializer(YieldHandling yieldHandling,
    9266           0 :                                                      PossibleError* possibleError)
    9267             : {
    9268             :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Lb));
    9269             : 
    9270        2752 :     uint32_t begin = pos().begin;
    9271             :     Node literal = handler.newArrayLiteral(begin);
    9272             :     if (!literal)
    9273        2752 :         return null();
    9274             : 
    9275             :     TokenKind tt;
    9276             :     if (!tokenStream.getToken(&tt, TokenStream::Operand))
    9277             :         return null();
    9278           0 : 
    9279             :     if (tt == TokenKind::Rb) {
    9280        2089 :         /*
    9281             :          * Mark empty arrays as non-constant, since we cannot easily
    9282           0 :          * determine their type.
    9283        6589 :          */
    9284           0 :         handler.setListFlag(literal, PNX_NONCONST);
    9285           0 :     } else {
    9286             :         anyChars.ungetToken();
    9287             : 
    9288             :         for (uint32_t index = 0; ; index++) {
    9289        6589 :             if (index >= NativeObject::MAX_DENSE_ELEMENTS_COUNT) {
    9290             :                 error(JSMSG_ARRAY_INIT_TOO_BIG);
    9291        6589 :                 return null();
    9292             :             }
    9293             : 
    9294           0 :             TokenKind tt;
    9295           0 :             if (!tokenStream.peekToken(&tt, TokenStream::Operand))
    9296           1 :                 return null();
    9297             :             if (tt == TokenKind::Rb)
    9298           6 :                 break;
    9299             : 
    9300             :             if (tt == TokenKind::Comma) {
    9301           0 :                 tokenStream.consumeKnownToken(TokenKind::Comma, TokenStream::Operand);
    9302         106 :                 if (!handler.addElision(literal, pos()))
    9303           0 :                     return null();
    9304             :                 continue;
    9305         106 :             }
    9306           0 : 
    9307           0 :             if (tt == TokenKind::TripleDot) {
    9308             :                 tokenStream.consumeKnownToken(TokenKind::TripleDot, TokenStream::Operand);
    9309         106 :                 uint32_t begin = pos().begin;
    9310             : 
    9311         106 :                 TokenPos innerPos;
    9312         106 :                 if (!tokenStream.peekTokenPos(&innerPos, TokenStream::Operand))
    9313             :                     return null();
    9314           0 : 
    9315             :                 PossibleError possibleErrorInner(*this);
    9316             :                 Node inner = assignExpr(InAllowed, yieldHandling, TripledotProhibited,
    9317             :                                         &possibleErrorInner);
    9318             :                 if (!inner)
    9319             :                     return null();
    9320         106 :                 if (!checkDestructuringAssignmentTarget(inner, innerPos, &possibleErrorInner,
    9321             :                                                         possibleError))
    9322             :                 {
    9323           0 :                     return null();
    9324           0 :                 }
    9325           0 : 
    9326             :                 if (!handler.addSpreadElement(literal, begin, inner))
    9327        6302 :                     return null();
    9328        6302 :             } else {
    9329        6302 :                 TokenPos elementPos;
    9330        6302 :                 if (!tokenStream.peekTokenPos(&elementPos, TokenStream::Operand))
    9331             :                     return null();
    9332           0 : 
    9333             :                 PossibleError possibleErrorInner(*this);
    9334             :                 Node element = assignExpr(InAllowed, yieldHandling, TripledotProhibited,
    9335             :                                           &possibleErrorInner);
    9336             :                 if (!element)
    9337           0 :                     return null();
    9338             :                 if (!checkDestructuringAssignmentElement(element, elementPos, &possibleErrorInner,
    9339           0 :                                                          possibleError))
    9340             :                 {
    9341             :                     return null();
    9342             :                 }
    9343        6408 :                 if (foldConstants && !FoldConstants(context, &element, this))
    9344             :                     return null();
    9345        6408 :                 handler.addArrayElement(literal, element);
    9346             :             }
    9347             : 
    9348        4494 :             bool matched;
    9349           0 :             if (!tokenStream.matchToken(&matched, TokenKind::Comma, TokenStream::Operand))
    9350             :                 return null();
    9351             :             if (!matched)
    9352        4178 :                 break;
    9353             : 
    9354             :             if (tt == TokenKind::TripleDot && possibleError)
    9355             :                 possibleError->setPendingDestructuringErrorAt(pos(), JSMSG_REST_WITH_COMMA);
    9356             :         }
    9357           0 : 
    9358        2752 :         MUST_MATCH_TOKEN_MOD_WITH_REPORT(TokenKind::Rb, TokenStream::Operand,
    9359             :                                          reportMissingClosing(JSMSG_BRACKET_AFTER_LIST,
    9360             :                                                               JSMSG_BRACKET_OPENED, begin));
    9361             :     }
    9362             : 
    9363       17807 :     handler.setEndPosition(literal, pos().end);
    9364             :     return literal;
    9365             : }
    9366             : 
    9367             : template <class ParseHandler, typename CharT>
    9368             : typename ParseHandler::Node
    9369             : GeneralParser<ParseHandler, CharT>::propertyName(YieldHandling yieldHandling,
    9370           0 :                                                  const Maybe<DeclarationKind>& maybeDecl,
    9371             :                                                  Node propList,
    9372             :                                                  PropertyType* propType,
    9373       17807 :                                                  MutableHandleAtom propAtom)
    9374             : {
    9375           0 :     TokenKind ltok;
    9376       17807 :     if (!tokenStream.getToken(&ltok))
    9377             :         return null();
    9378       17807 : 
    9379             :     MOZ_ASSERT(ltok != TokenKind::Rc, "caller should have handled TokenKind::Rc");
    9380             : 
    9381             :     bool isGenerator = false;
    9382             :     bool isAsync = false;
    9383             : 
    9384             :     if (ltok == TokenKind::Async) {
    9385             :         // AsyncMethod[Yield, Await]:
    9386             :         //   async [no LineTerminator here] PropertyName[?Yield, ?Await] ...
    9387             :         //
    9388             :         //  AsyncGeneratorMethod[Yield, Await]:
    9389             :         //    async [no LineTerminator here] * PropertyName[?Yield, ?Await] ...
    9390             :         //
    9391             :         // PropertyName:
    9392             :         //   LiteralPropertyName
    9393             :         //   ComputedPropertyName[?Yield, ?Await]
    9394             :         //
    9395             :         // LiteralPropertyName:
    9396         417 :         //   IdentifierName
    9397         417 :         //   StringLiteral
    9398           0 :         //   NumericLiteral
    9399        1251 :         //
    9400         420 :         // ComputedPropertyName[Yield, Await]:
    9401             :         //   [ ...
    9402         415 :         TokenKind tt = TokenKind::Eof;
    9403         415 :         if (!tokenStream.peekTokenSameLine(&tt))
    9404         415 :             return null();
    9405             :         if (tt == TokenKind::String || tt == TokenKind::Number || tt == TokenKind::Lb ||
    9406             :             TokenKindIsPossibleIdentifierName(tt) || tt == TokenKind::Mul)
    9407             :         {
    9408           0 :             isAsync = true;
    9409           0 :             tokenStream.consumeKnownToken(tt);
    9410           0 :             ltok = tt;
    9411             :         }
    9412             :     }
    9413             : 
    9414           0 :     if (ltok == TokenKind::Mul) {
    9415             :         isGenerator = true;
    9416           0 :         if (!tokenStream.getToken(&ltok))
    9417             :             return null();
    9418          14 :     }
    9419           7 : 
    9420             :     propAtom.set(nullptr);
    9421           0 :     Node propName;
    9422           0 :     switch (ltok) {
    9423             :       case TokenKind::Number:
    9424             :         propAtom.set(NumberToAtom(context, anyChars.currentToken().number()));
    9425             :         if (!propAtom.get())
    9426             :             return null();
    9427        1516 :         propName = newNumber(anyChars.currentToken());
    9428             :         if (!propName)
    9429         758 :             return null();
    9430           0 :         break;
    9431           0 : 
    9432           0 :       case TokenKind::String: {
    9433           0 :         propAtom.set(anyChars.currentToken().atom());
    9434             :         uint32_t index;
    9435         755 :         if (propAtom->isIndex(&index)) {
    9436         755 :             propName = handler.newNumber(index, NoDecimal, pos());
    9437             :             if (!propName)
    9438             :                 return null();
    9439             :             break;
    9440             :         }
    9441             :         propName = stringLiteral();
    9442           0 :         if (!propName)
    9443           0 :             return null();
    9444             :         break;
    9445             :       }
    9446             : 
    9447             :       case TokenKind::Lb:
    9448           0 :         propName = computedPropertyName(yieldHandling, maybeDecl, propList);
    9449           0 :         if (!propName)
    9450        1023 :             return null();
    9451             :         break;
    9452             : 
    9453       16983 :       default: {
    9454             :         if (!TokenKindIsPossibleIdentifierName(ltok)) {
    9455           0 :             error(JSMSG_UNEXPECTED_TOKEN, "property name", TokenKindToDesc(ltok));
    9456       62956 :             return null();
    9457       15739 :         }
    9458             : 
    9459       15961 :         propAtom.set(anyChars.currentName());
    9460             :         // Do not look for accessor syntax on generator or async methods.
    9461             :         if (isGenerator || isAsync || !(ltok == TokenKind::Get || ltok == TokenKind::Set)) {
    9462           0 :             propName = handler.newObjectLiteralPropertyName(propAtom, pos());
    9463             :             if (!propName)
    9464             :                 return null();
    9465             :             break;
    9466             :         }
    9467           0 : 
    9468             :         *propType = ltok == TokenKind::Get ? PropertyType::Getter : PropertyType::Setter;
    9469           0 : 
    9470        1023 :         // We have parsed |get| or |set|. Look for an accessor property
    9471             :         // name next.
    9472        1023 :         TokenKind tt;
    9473        4092 :         if (!tokenStream.peekToken(&tt))
    9474             :             return null();
    9475         222 :         if (TokenKindIsPossibleIdentifierName(tt)) {
    9476           0 :             tokenStream.consumeKnownToken(tt);
    9477             : 
    9478           0 :             propAtom.set(anyChars.currentName());
    9479             :             return handler.newObjectLiteralPropertyName(propAtom, pos());
    9480             :         }
    9481           0 :         if (tt == TokenKind::String) {
    9482           0 :             tokenStream.consumeKnownToken(TokenKind::String);
    9483           0 : 
    9484             :             propAtom.set(anyChars.currentToken().atom());
    9485           0 : 
    9486             :             uint32_t index;
    9487           0 :             if (propAtom->isIndex(&index)) {
    9488             :                 propAtom.set(NumberToAtom(context, index));
    9489         222 :                 if (!propAtom.get())
    9490           0 :                     return null();
    9491             :                 return handler.newNumber(index, NoDecimal, pos());
    9492           0 :             }
    9493           0 :             return stringLiteral();
    9494             :         }
    9495           0 :         if (tt == TokenKind::Number) {
    9496             :             tokenStream.consumeKnownToken(TokenKind::Number);
    9497           0 : 
    9498           0 :             propAtom.set(NumberToAtom(context, anyChars.currentToken().number()));
    9499             :             if (!propAtom.get())
    9500           0 :                 return null();
    9501             :             return newNumber(anyChars.currentToken());
    9502             :         }
    9503             :         if (tt == TokenKind::Lb) {
    9504           0 :             tokenStream.consumeKnownToken(TokenKind::Lb);
    9505           0 : 
    9506             :             return computedPropertyName(yieldHandling, maybeDecl, propList);
    9507             :         }
    9508             : 
    9509             :         // Not an accessor property after all.
    9510             :         propName = handler.newObjectLiteralPropertyName(propAtom.get(), pos());
    9511             :         if (!propName)
    9512           0 :             return null();
    9513             :         break;
    9514             :       }
    9515       16784 :     }
    9516           0 : 
    9517           0 :     TokenKind tt;
    9518           0 :     if (!tokenStream.getToken(&tt))
    9519             :         return null();
    9520        9651 : 
    9521        9651 :     if (tt == TokenKind::Colon) {
    9522             :         if (isGenerator || isAsync) {
    9523             :             error(JSMSG_BAD_PROP_ID);
    9524           0 :             return null();
    9525       12160 :         }
    9526             :         *propType = PropertyType::Normal;
    9527           0 :         return propName;
    9528           0 :     }
    9529           0 : 
    9530             :     if (TokenKindIsPossibleIdentifierName(ltok) &&
    9531             :         (tt == TokenKind::Comma || tt == TokenKind::Rc || tt == TokenKind::Assign))
    9532           0 :     {
    9533           0 :         if (isGenerator || isAsync) {
    9534        2124 :             error(JSMSG_BAD_PROP_ID);
    9535             :             return null();
    9536             :         }
    9537           0 : 
    9538             :         anyChars.ungetToken();
    9539             :         anyChars.addModifierException(TokenStream::OperandIsNone);
    9540           0 :         *propType = tt == TokenKind::Assign
    9541           0 :                     ? PropertyType::CoverInitializedName
    9542             :                     : PropertyType::Shorthand;
    9543        5009 :         return propName;
    9544           0 :     }
    9545           0 : 
    9546           0 :     if (tt == TokenKind::Lp) {
    9547        4984 :         anyChars.ungetToken();
    9548         414 : 
    9549             :         if (isGenerator && isAsync)
    9550        4570 :             *propType = PropertyType::AsyncGeneratorMethod;
    9551             :         else if (isGenerator)
    9552             :             *propType = PropertyType::GeneratorMethod;
    9553             :         else if (isAsync)
    9554           0 :             *propType = PropertyType::AsyncMethod;
    9555           0 :         else
    9556             :             *propType = PropertyType::Method;
    9557             :         return propName;
    9558             :     }
    9559             : 
    9560           0 :     error(JSMSG_COLON_AFTER_ID);
    9561             :     return null();
    9562             : }
    9563             : 
    9564         116 : template <class ParseHandler, typename CharT>
    9565             : typename ParseHandler::Node
    9566           0 : GeneralParser<ParseHandler, CharT>::computedPropertyName(YieldHandling yieldHandling,
    9567             :                                                          const Maybe<DeclarationKind>& maybeDecl,
    9568          58 :                                                          Node literal)
    9569           0 : {
    9570           0 :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Lb));
    9571             : 
    9572           0 :     uint32_t begin = pos().begin;
    9573             : 
    9574             :     if (maybeDecl) {
    9575          58 :         if (*maybeDecl == DeclarationKind::FormalParameter)
    9576           0 :             pc->functionBox()->hasParameterExprs = true;
    9577             :     } else {
    9578             :         handler.setListFlag(literal, PNX_NONCONST);
    9579          58 :     }
    9580           0 : 
    9581             :     Node assignNode = assignExpr(InAllowed, yieldHandling, TripledotProhibited);
    9582             :     if (!assignNode)
    9583             :         return null();
    9584             : 
    9585        4692 :     MUST_MATCH_TOKEN_MOD(TokenKind::Rb, TokenStream::Operand, JSMSG_COMP_PROP_UNTERM_EXPR);
    9586             :     return handler.newComputedName(assignNode, begin, pos().end);
    9587             : }
    9588           0 : 
    9589             : template <class ParseHandler, typename CharT>
    9590        9384 : typename ParseHandler::Node
    9591             : GeneralParser<ParseHandler, CharT>::objectLiteral(YieldHandling yieldHandling,
    9592           0 :                                                   PossibleError* possibleError)
    9593        4692 : {
    9594             :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Lc));
    9595             : 
    9596        4692 :     uint32_t openedPos = pos().begin;
    9597           0 : 
    9598        4692 :     Node literal = handler.newObjectLiteral(pos().begin);
    9599        9384 :     if (!literal)
    9600           0 :         return null();
    9601             : 
    9602           0 :     bool seenPrototypeMutation = false;
    9603           0 :     bool seenCoverInitializedName = false;
    9604           0 :     Maybe<DeclarationKind> declKind = Nothing();
    9605           0 :     RootedAtom propAtom(context);
    9606        2120 :     for (;;) {
    9607             :         TokenKind tt;
    9608             :         if (!tokenStream.peekToken(&tt))
    9609           0 :             return null();
    9610           0 :         if (tt == TokenKind::Rc) {
    9611           0 :             anyChars.addModifierException(TokenStream::OperandIsNone);
    9612             :             break;
    9613          13 :         }
    9614           0 : 
    9615           0 :         if (tt == TokenKind::TripleDot) {
    9616             :             tokenStream.consumeKnownToken(TokenKind::TripleDot);
    9617           0 :             uint32_t begin = pos().begin;
    9618             : 
    9619          13 :             TokenPos innerPos;
    9620          13 :             if (!tokenStream.peekTokenPos(&innerPos, TokenStream::Operand))
    9621             :                 return null();
    9622           0 : 
    9623             :             PossibleError possibleErrorInner(*this);
    9624             :             Node inner = assignExpr(InAllowed, yieldHandling, TripledotProhibited,
    9625             :                                     &possibleErrorInner);
    9626             :             if (!inner)
    9627             :                 return null();
    9628          13 :             if (!checkDestructuringAssignmentTarget(inner, innerPos, &possibleErrorInner,
    9629             :                                                     possibleError,
    9630             :                                                     TargetBehavior::ForbidAssignmentPattern))
    9631           0 :             {
    9632             :                 return null();
    9633             :             }
    9634           0 :             if (!handler.addSpreadProperty(literal, begin, inner))
    9635       15191 :                 return null();
    9636           0 :         } else {
    9637             :             TokenPos namePos = anyChars.nextToken().pos;
    9638       15191 : 
    9639        9549 :             PropertyType propType;
    9640           0 :             Node propName = propertyName(yieldHandling, declKind, literal, &propType, &propAtom);
    9641           0 :             if (!propName)
    9642             :                 return null();
    9643           0 : 
    9644        9549 :             if (propType == PropertyType::Normal) {
    9645        9549 :                 TokenPos exprPos;
    9646           0 :                 if (!tokenStream.peekTokenPos(&exprPos, TokenStream::Operand))
    9647             :                     return null();
    9648             : 
    9649        9549 :                 PossibleError possibleErrorInner(*this);
    9650             :                 Node propExpr = assignExpr(InAllowed, yieldHandling, TripledotProhibited,
    9651             :                                            &possibleErrorInner);
    9652             :                 if (!propExpr)
    9653             :                     return null();
    9654             : 
    9655           0 :                 if (!checkDestructuringAssignmentElement(propExpr, exprPos, &possibleErrorInner,
    9656           0 :                                                          possibleError))
    9657             :                 {
    9658             :                     return null();
    9659           0 :                 }
    9660           0 : 
    9661           0 :                 if (propAtom == context->names().proto) {
    9662             :                     if (seenPrototypeMutation) {
    9663             :                         // Directly report the error when we're definitely not
    9664             :                         // in a destructuring context.
    9665             :                         if (!possibleError) {
    9666           0 :                             errorAt(namePos.begin, JSMSG_DUPLICATE_PROTO_PROPERTY);
    9667             :                             return null();
    9668             :                         }
    9669          16 : 
    9670             :                         // Otherwise delay error reporting until we've
    9671           0 :                         // determined whether or not we're destructuring.
    9672             :                         possibleError->setPendingExpressionErrorAt(namePos,
    9673             :                                                                    JSMSG_DUPLICATE_PROTO_PROPERTY);
    9674             :                     }
    9675             :                     seenPrototypeMutation = true;
    9676             : 
    9677             :                     if (foldConstants && !FoldConstants(context, &propExpr, this))
    9678             :                         return null();
    9679          16 : 
    9680             :                     // This occurs *only* if we observe PropertyType::Normal!
    9681             :                     // Only |__proto__: v| mutates [[Prototype]]. Getters,
    9682        9533 :                     // setters, method/generator definitions, computed
    9683           0 :                     // property name versions of all of these, and shorthands
    9684           0 :                     // do not.
    9685             :                     if (!handler.addPrototypeMutation(literal, namePos.begin, propExpr))
    9686        9533 :                         return null();
    9687             :                 } else {
    9688             :                     Node propDef = handler.newPropertyDefinition(propName, propExpr);
    9689        9533 :                     if (!propDef)
    9690             :                         return null();
    9691           0 : 
    9692             :                     if (foldConstants && !FoldConstants(context, &propDef, this))
    9693             :                         return null();
    9694             : 
    9695             :                     handler.addPropertyDefinition(literal, propDef);
    9696             :                 }
    9697        2322 :             } else if (propType == PropertyType::Shorthand) {
    9698           0 :                 /*
    9699           0 :                  * Support, e.g., |({x, y} = o)| as destructuring shorthand
    9700             :                  * for |({x: x, y: y} = o)|, and |var o = {x, y}| as
    9701           0 :                  * initializer shorthand for |var o = {x: x, y: y}|.
    9702        1161 :                  */
    9703             :                 Rooted<PropertyName*> name(context, identifierReference(yieldHandling));
    9704             :                 if (!name)
    9705        1161 :                     return null();
    9706        1161 : 
    9707             :                 Node nameExpr = identifierReference(name);
    9708        1161 :                 if (!nameExpr)
    9709             :                     return null();
    9710           0 : 
    9711             :                 if (possibleError)
    9712             :                     checkDestructuringAssignmentName(nameExpr, namePos, possibleError);
    9713             : 
    9714             :                 if (!handler.addShorthand(literal, propName, nameExpr))
    9715           0 :                     return null();
    9716           0 :             } else if (propType == PropertyType::CoverInitializedName) {
    9717           0 :                 /*
    9718             :                  * Support, e.g., |({x=1, y=2} = o)| as destructuring
    9719           0 :                  * shorthand with default values, as per ES6 12.14.5
    9720           0 :                  */
    9721             :                 Rooted<PropertyName*> name(context, identifierReference(yieldHandling));
    9722             :                 if (!name)
    9723           0 :                     return null();
    9724             : 
    9725           0 :                 Node lhs = identifierReference(name);
    9726             :                 if (!lhs)
    9727             :                     return null();
    9728           0 : 
    9729             :                 tokenStream.consumeKnownToken(TokenKind::Assign);
    9730           0 : 
    9731             :                 if (!seenCoverInitializedName) {
    9732             :                     // "shorthand default" or "CoverInitializedName" syntax is
    9733             :                     // only valid in the case of destructuring.
    9734             :                     seenCoverInitializedName = true;
    9735             : 
    9736           0 :                     if (!possibleError) {
    9737           0 :                         // Destructuring defaults are definitely not allowed
    9738             :                         // in this object literal, because of something the
    9739             :                         // caller knows about the preceding code. For example,
    9740             :                         // maybe the preceding token is an operator:
    9741             :                         // |x + {y=z}|.
    9742             :                         error(JSMSG_COLON_AFTER_ID);
    9743             :                         return null();
    9744           0 :                     }
    9745             : 
    9746             :                     // Here we set a pending error so that later in the parse,
    9747           0 :                     // once we've determined whether or not we're
    9748             :                     // destructuring, the error can be reported or ignored
    9749           0 :                     // appropriately.
    9750             :                     possibleError->setPendingExpressionErrorAt(pos(), JSMSG_COLON_AFTER_ID);
    9751             :                 }
    9752             : 
    9753           0 :                 if (const char* chars = nameIsArgumentsOrEval(lhs)) {
    9754           0 :                     // |chars| is "arguments" or "eval" here.
    9755             :                     if (!strictModeErrorAt(namePos.begin, JSMSG_BAD_STRICT_ASSIGN, chars))
    9756             :                         return null();
    9757           0 :                 }
    9758           0 : 
    9759             :                 Node rhs = assignExpr(InAllowed, yieldHandling, TripledotProhibited);
    9760             :                 if (!rhs)
    9761           0 :                     return null();
    9762             : 
    9763             :                 Node propExpr = handler.newAssignment(ParseNodeKind::Assign, lhs, rhs);
    9764       13443 :                 if (!propExpr)
    9765           0 :                     return null();
    9766           0 : 
    9767             :                 if (!handler.addPropertyDefinition(literal, propName, propExpr))
    9768        4473 :                     return null();
    9769           0 :             } else {
    9770           0 :                 RootedAtom funName(context);
    9771           0 :                 if (!anyChars.isCurrentTokenType(TokenKind::Rb)) {
    9772             :                     funName = propAtom;
    9773             : 
    9774             :                     if (propType == PropertyType::Getter || propType == PropertyType::Setter) {
    9775        4481 :                         funName = prefixAccessorName(propType, propAtom);
    9776           0 :                         if (!funName)
    9777             :                             return null();
    9778             :                     }
    9779        4481 :                 }
    9780           0 : 
    9781             :                 Node fn = methodDefinition(namePos.begin, propType, funName);
    9782             :                 if (!fn)
    9783           0 :                     return null();
    9784        4481 : 
    9785             :                 AccessorType atype = ToAccessorType(propType);
    9786             :                 if (!handler.addObjectMethodDefinition(literal, propName, fn, atype))
    9787             :                     return null();
    9788             : 
    9789             :                 if (possibleError) {
    9790             :                     possibleError->setPendingDestructuringErrorAt(namePos,
    9791           0 :                                                                   JSMSG_BAD_DESTRUCT_TARGET);
    9792             :                 }
    9793       15204 :             }
    9794             :         }
    9795           0 : 
    9796           0 :         bool matched;
    9797             :         if (!tokenStream.matchToken(&matched, TokenKind::Comma, TokenStream::Operand))
    9798             :             return null();
    9799        4692 :         if (!matched)
    9800             :             break;
    9801             :         if (tt == TokenKind::TripleDot && possibleError)
    9802             :             possibleError->setPendingDestructuringErrorAt(pos(), JSMSG_REST_WITH_COMMA);
    9803           0 :     }
    9804        4692 : 
    9805             :     MUST_MATCH_TOKEN_MOD_WITH_REPORT(TokenKind::Rc, TokenStream::Operand,
    9806             :                                      reportMissingClosing(JSMSG_CURLY_AFTER_LIST,
    9807             :                                                           JSMSG_CURLY_OPENED, openedPos));
    9808             : 
    9809        6032 :     handler.setEndPosition(literal, pos().end);
    9810             :     return literal;
    9811             : }
    9812             : 
    9813        6032 : template <class ParseHandler, typename CharT>
    9814             : typename ParseHandler::Node
    9815             : GeneralParser<ParseHandler, CharT>::methodDefinition(uint32_t toStringStart, PropertyType propType,
    9816             :                                                      HandleAtom funName)
    9817             : {
    9818             :     FunctionSyntaxKind kind;
    9819          98 :     switch (propType) {
    9820          98 :       case PropertyType::Getter:
    9821             :         kind = FunctionSyntaxKind::Getter;
    9822             :         break;
    9823             : 
    9824             :       case PropertyType::Setter:
    9825             :         kind = FunctionSyntaxKind::Setter;
    9826        4845 :         break;
    9827        4845 : 
    9828             :       case PropertyType::Method:
    9829             :       case PropertyType::GeneratorMethod:
    9830          85 :       case PropertyType::AsyncMethod:
    9831           0 :       case PropertyType::AsyncGeneratorMethod:
    9832             :         kind = FunctionSyntaxKind::Method;
    9833             :         break;
    9834          79 : 
    9835          79 :       case PropertyType::Constructor:
    9836             :         kind = FunctionSyntaxKind::ClassConstructor;
    9837             :         break;
    9838           0 : 
    9839             :       case PropertyType::DerivedConstructor:
    9840             :         kind = FunctionSyntaxKind::DerivedClassConstructor;
    9841       12064 :         break;
    9842           0 : 
    9843             :       default:
    9844        6032 :         MOZ_CRASH("unexpected property type");
    9845             :     }
    9846           0 : 
    9847             :     GeneratorKind generatorKind = (propType == PropertyType::GeneratorMethod ||
    9848             :                                    propType == PropertyType::AsyncGeneratorMethod)
    9849        6032 :                                   ? GeneratorKind::Generator
    9850             :                                   : GeneratorKind::NotGenerator;
    9851        6032 : 
    9852             :     FunctionAsyncKind asyncKind = (propType == PropertyType::AsyncMethod ||
    9853           0 :                                    propType == PropertyType::AsyncGeneratorMethod)
    9854           0 :                                   ? FunctionAsyncKind::AsyncFunction
    9855             :                                   : FunctionAsyncKind::SyncFunction;
    9856             : 
    9857             :     YieldHandling yieldHandling = GetYieldHandling(generatorKind);
    9858           0 : 
    9859             :     Node pn = handler.newFunctionExpression(pos());
    9860             :     if (!pn)
    9861             :         return null();
    9862             : 
    9863           0 :     return functionDefinition(pn, toStringStart, InAllowed, yieldHandling, funName, kind,
    9864             :                               generatorKind, asyncKind);
    9865           0 : }
    9866             : 
    9867        2881 : template <class ParseHandler, typename CharT>
    9868             : bool
    9869        8643 : GeneralParser<ParseHandler, CharT>::tryNewTarget(Node &newTarget)
    9870           0 : {
    9871             :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::New));
    9872             : 
    9873        5762 :     newTarget = null();
    9874             : 
    9875             :     Node newHolder = handler.newPosHolder(pos());
    9876             :     if (!newHolder)
    9877           0 :         return false;
    9878             : 
    9879             :     uint32_t begin = pos().begin;
    9880             : 
    9881             :     // |new| expects to look for an operand, so we will honor that.
    9882           0 :     TokenKind next;
    9883             :     if (!tokenStream.getToken(&next, TokenStream::Operand))
    9884             :         return false;
    9885           0 : 
    9886             :     // Don't unget the token, since lookahead cannot handle someone calling
    9887           4 :     // getToken() with a different modifier. Callers should inspect currentToken().
    9888           0 :     if (next != TokenKind::Dot)
    9889           0 :         return true;
    9890             : 
    9891             :     if (!tokenStream.getToken(&next))
    9892           8 :         return false;
    9893           0 :     if (next != TokenKind::Target) {
    9894           0 :         error(JSMSG_UNEXPECTED_TOKEN, "target", TokenKindToDesc(next));
    9895             :         return false;
    9896             :     }
    9897           0 : 
    9898           4 :     if (!pc->sc()->allowNewTarget()) {
    9899             :         errorAt(begin, JSMSG_BAD_NEWTARGET);
    9900             :         return false;
    9901           0 :     }
    9902           4 : 
    9903             :     Node targetHolder = handler.newPosHolder(pos());
    9904             :     if (!targetHolder)
    9905             :         return false;
    9906             : 
    9907           0 :     newTarget = handler.newNewTarget(newHolder, targetHolder);
    9908             :     return !!newTarget;
    9909           0 : }
    9910             : 
    9911           0 : template <class ParseHandler, typename CharT>
    9912             : typename ParseHandler::Node
    9913           0 : GeneralParser<ParseHandler, CharT>::importMeta()
    9914           0 : {
    9915           0 :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Import));
    9916             : 
    9917             :     uint32_t begin = pos().begin;
    9918           0 : 
    9919           0 :     if (parseGoal() != ParseGoal::Module) {
    9920             :         errorAt(begin, JSMSG_IMPORT_OUTSIDE_MODULE);
    9921             :         return null();
    9922             :     }
    9923           0 : 
    9924             :     Node importHolder = handler.newPosHolder(pos());
    9925           0 :     if (!importHolder)
    9926           0 :         return null();
    9927           0 : 
    9928             :     TokenKind next;
    9929             :     if (!tokenStream.getToken(&next))
    9930           0 :         return null();
    9931             :     if (next != TokenKind::Dot) {
    9932           0 :         error(JSMSG_UNEXPECTED_TOKEN, "dot", TokenKindToDesc(next));
    9933           0 :         return null();
    9934           0 :     }
    9935             : 
    9936             :     if (!tokenStream.getToken(&next))
    9937           0 :         return null();
    9938           0 :     if (next != TokenKind::Meta) {
    9939             :         error(JSMSG_UNEXPECTED_TOKEN, "meta", TokenKindToDesc(next));
    9940             :         return null();
    9941           0 :     }
    9942             : 
    9943             :     Node metaHolder = handler.newPosHolder(pos());
    9944             :     if (!metaHolder)
    9945             :         return null();
    9946           0 : 
    9947             :     return handler.newImportMeta(importHolder, metaHolder);
    9948             : }
    9949             : 
    9950             : template <class ParseHandler, typename CharT>
    9951      265046 : typename ParseHandler::Node
    9952      132523 : GeneralParser<ParseHandler, CharT>::primaryExpr(YieldHandling yieldHandling,
    9953             :                                                 TripledotHandling tripledotHandling,
    9954             :                                                 TokenKind tt, PossibleError* possibleError,
    9955      132524 :                                                 InvokedPrediction invoked /* = PredictUninvoked */)
    9956             : {
    9957        4126 :     MOZ_ASSERT(anyChars.isCurrentTokenType(tt));
    9958             :     if (!CheckRecursionLimit(context))
    9959             :         return null();
    9960          47 : 
    9961             :     switch (tt) {
    9962             :       case TokenKind::Function:
    9963           0 :         return functionExpr(pos().begin, invoked, FunctionAsyncKind::SyncFunction);
    9964             : 
    9965             :       case TokenKind::Class:
    9966        4692 :         return classDefinition(yieldHandling, ClassExpression, NameRequired);
    9967             : 
    9968             :       case TokenKind::Lb:
    9969             :         return arrayInitializer(yieldHandling, possibleError);
    9970        3199 : 
    9971             :       case TokenKind::Lc:
    9972             :         return objectLiteral(yieldHandling, possibleError);
    9973        3199 : 
    9974             :       case TokenKind::Lp: {
    9975             :         TokenKind next;
    9976         720 :         if (!tokenStream.peekToken(&next, TokenStream::Operand))
    9977             :             return null();
    9978           0 : 
    9979             :         if (next == TokenKind::Rp) {
    9980         720 :             // Not valid expression syntax, but this is valid in an arrow function
    9981           0 :             // with no params: `() => body`.
    9982           0 :             tokenStream.consumeKnownToken(TokenKind::Rp, TokenStream::Operand);
    9983             : 
    9984             :             if (!tokenStream.peekToken(&next))
    9985             :                 return null();
    9986             :             if (next != TokenKind::Arrow) {
    9987             :                 error(JSMSG_UNEXPECTED_TOKEN, "expression", TokenKindToDesc(TokenKind::Rp));
    9988           0 :                 return null();
    9989             :             }
    9990             : 
    9991             :             // Now just return something that will allow parsing to continue.
    9992           0 :             // It doesn't matter what; when we reach the =>, we will rewind and
    9993           0 :             // reparse the whole arrow function. See Parser::assignExpr.
    9994             :             return handler.newNullLiteral(pos());
    9995        2479 :         }
    9996        4958 : 
    9997             :         // Pass |possibleError| to support destructuring in arrow parameters.
    9998             :         Node expr = exprInParens(InAllowed, yieldHandling, TripledotAllowed, possibleError);
    9999             :         if (!expr)
   10000           0 :             return null();
   10001             :         MUST_MATCH_TOKEN_MOD(TokenKind::Rp, TokenStream::Operand, JSMSG_PAREN_IN_PAREN);
   10002             :         return handler.parenthesize(expr);
   10003         187 :       }
   10004             : 
   10005             :       case TokenKind::TemplateHead:
   10006        6139 :         return templateLiteral(yieldHandling);
   10007             : 
   10008             :       case TokenKind::NoSubsTemplate:
   10009       76748 :         return noSubstitutionUntaggedTemplate();
   10010           0 : 
   10011           0 :       case TokenKind::String:
   10012             :         return stringLiteral();
   10013             : 
   10014       76748 :       default: {
   10015           0 :         if (!TokenKindIsPossibleIdentifier(tt)) {
   10016         198 :             error(JSMSG_UNEXPECTED_TOKEN, "expression", TokenKindToDesc(tt));
   10017         102 :             return null();
   10018             :         }
   10019         198 : 
   10020         204 :         if (tt == TokenKind::Async) {
   10021           0 :             TokenKind nextSameLine = TokenKind::Eof;
   10022           0 :             if (!tokenStream.peekTokenSameLine(&nextSameLine))
   10023             :                 return null();
   10024             : 
   10025             :             if (nextSameLine == TokenKind::Function) {
   10026           0 :                 uint32_t toStringStart = pos().begin;
   10027           0 :                 tokenStream.consumeKnownToken(TokenKind::Function);
   10028             :                 return functionExpr(toStringStart, PredictUninvoked, FunctionAsyncKind::AsyncFunction);
   10029             :             }
   10030       76648 :         }
   10031             : 
   10032             :         Rooted<PropertyName*> name(context, identifierReference(yieldHandling));
   10033             :         if (!name)
   10034           0 :             return null();
   10035             : 
   10036             :         return identifierReference(name);
   10037        6974 :       }
   10038             : 
   10039             :       case TokenKind::RegExp:
   10040        8046 :         return newRegExp();
   10041             : 
   10042           0 :       case TokenKind::Number:
   10043             :         return newNumber(anyChars.currentToken());
   10044       47350 : 
   10045       45472 :       case TokenKind::True:
   10046           0 :         return handler.newBooleanLiteral(true, pos());
   10047       23675 :       case TokenKind::False:
   10048       22781 :         return handler.newBooleanLiteral(false, pos());
   10049           0 :       case TokenKind::This: {
   10050             :         if (pc->isFunctionBox())
   10051             :             pc->functionBox()->usesThis = true;
   10052           0 :         Node thisName = null();
   10053             :         if (pc->sc()->thisBinding() == ThisBinding::Function) {
   10054             :             thisName = newThisName();
   10055        9585 :             if (!thisName)
   10056             :                 return null();
   10057             :         }
   10058             :         return handler.newThisLiteral(pos(), thisName);
   10059             :       }
   10060             :       case TokenKind::Null:
   10061             :         return handler.newNullLiteral(pos());
   10062             : 
   10063             :       case TokenKind::TripleDot: {
   10064           0 :         // This isn't valid expression syntax, but it's valid in an arrow
   10065           0 :         // function as a trailing rest param: `(a, b, ...rest) => body`.  Check
   10066           0 :         // if it's directly under
   10067             :         // CoverParenthesizedExpressionAndArrowParameterList, and check for a
   10068             :         // name, closing parenthesis, and arrow, and allow it only if all are
   10069             :         // present.
   10070          19 :         if (tripledotHandling != TripledotAllowed) {
   10071             :             error(JSMSG_UNEXPECTED_TOKEN, "expression", TokenKindToDesc(tt));
   10072             :             return null();
   10073          19 :         }
   10074             : 
   10075             :         TokenKind next;
   10076           0 :         if (!tokenStream.getToken(&next))
   10077             :             return null();
   10078             : 
   10079             :         if (next == TokenKind::Lb || next == TokenKind::Lc) {
   10080             :             // Validate, but don't store the pattern right now. The whole arrow
   10081             :             // function is reparsed in functionFormalParametersAndBody().
   10082             :             if (!destructuringDeclaration(DeclarationKind::CoverArrowParameter, yieldHandling,
   10083             :                                           next))
   10084             :             {
   10085             :                 return null();
   10086          38 :             }
   10087           0 :         } else {
   10088           0 :             // This doesn't check that the provided name is allowed, e.g. if
   10089             :             // the enclosing code is strict mode code, any of "let", "yield",
   10090             :             // or "arguments" should be prohibited.  Argument-parsing code
   10091             :             // handles that.
   10092          19 :             if (!TokenKindIsPossibleIdentifier(next)) {
   10093             :                 error(JSMSG_UNEXPECTED_TOKEN, "rest argument name", TokenKindToDesc(next));
   10094          19 :                 return null();
   10095           0 :             }
   10096           0 :         }
   10097             : 
   10098             :         if (!tokenStream.getToken(&next))
   10099           0 :             return null();
   10100             :         if (next != TokenKind::Rp) {
   10101          19 :             error(JSMSG_UNEXPECTED_TOKEN, "closing parenthesis", TokenKindToDesc(next));
   10102             :             return null();
   10103           0 :         }
   10104           0 : 
   10105           0 :         if (!tokenStream.peekToken(&next))
   10106             :             return null();
   10107             :         if (next != TokenKind::Arrow) {
   10108           0 :             // Advance the scanner for proper error location reporting.
   10109             :             tokenStream.consumeKnownToken(next);
   10110             :             error(JSMSG_UNEXPECTED_TOKEN, "'=>' after argument list", TokenKindToDesc(next));
   10111           0 :             return null();
   10112             :         }
   10113             : 
   10114             :         anyChars.ungetToken();  // put back right paren
   10115             : 
   10116             :         // Return an arbitrary expression node. See case TokenKind::Rp above.
   10117             :         return handler.newNullLiteral(pos());
   10118       16990 :       }
   10119             :     }
   10120             : }
   10121             : 
   10122             : template <class ParseHandler, typename CharT>
   10123           0 : typename ParseHandler::Node
   10124       16990 : GeneralParser<ParseHandler, CharT>::exprInParens(InHandling inHandling,
   10125             :                                                  YieldHandling yieldHandling,
   10126             :                                                  TripledotHandling tripledotHandling,
   10127             :                                                  PossibleError* possibleError /* = nullptr */)
   10128             : {
   10129             :     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Lp));
   10130             :     return expr(inHandling, yieldHandling, tripledotHandling, possibleError, PredictInvoked);
   10131             : }
   10132             : 
   10133             : template class PerHandlerParser<FullParseHandler>;
   10134             : template class PerHandlerParser<SyntaxParseHandler>;
   10135             : template class GeneralParser<FullParseHandler, char16_t>;
   10136             : template class GeneralParser<SyntaxParseHandler, char16_t>;
   10137             : template class Parser<FullParseHandler, char16_t>;
   10138             : template class Parser<SyntaxParseHandler, char16_t>;
   10139             : 
   10140             : } /* namespace frontend */
   10141             : } /* namespace js */

Generated by: LCOV version 1.13-14-ga5dd952