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

Generated by: LCOV version 1.13