1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "frontend/ParseContext-inl.h"
9 #include "frontend/CompilationStencil.h" // ScopeContext
10 #include "frontend/Parser.h" // ParserBase
11 #include "js/friend/ErrorMessages.h" // JSMSG_*
14 using mozilla::Nothing
;
20 using AddDeclaredNamePtr
= ParseContext::Scope::AddDeclaredNamePtr
;
21 using DeclaredNamePtr
= ParseContext::Scope::DeclaredNamePtr
;
23 const char* DeclarationKindString(DeclarationKind kind
) {
25 case DeclarationKind::PositionalFormalParameter
:
26 case DeclarationKind::FormalParameter
:
27 return "formal parameter";
28 case DeclarationKind::CoverArrowParameter
:
29 return "cover arrow parameter";
30 case DeclarationKind::Var
:
32 case DeclarationKind::Let
:
34 case DeclarationKind::Const
:
36 case DeclarationKind::Class
:
38 case DeclarationKind::Import
:
40 case DeclarationKind::BodyLevelFunction
:
41 case DeclarationKind::ModuleBodyLevelFunction
:
42 case DeclarationKind::LexicalFunction
:
43 case DeclarationKind::SloppyLexicalFunction
:
45 case DeclarationKind::VarForAnnexBLexicalFunction
:
47 case DeclarationKind::SimpleCatchParameter
:
48 case DeclarationKind::CatchParameter
:
49 return "catch parameter";
50 case DeclarationKind::PrivateName
:
51 return "private name";
52 case DeclarationKind::Synthetic
:
54 case DeclarationKind::PrivateMethod
:
55 return "private method";
58 MOZ_CRASH("Bad DeclarationKind");
61 bool DeclarationKindIsVar(DeclarationKind kind
) {
62 return kind
== DeclarationKind::Var
||
63 kind
== DeclarationKind::BodyLevelFunction
||
64 kind
== DeclarationKind::VarForAnnexBLexicalFunction
;
67 bool DeclarationKindIsParameter(DeclarationKind kind
) {
68 return kind
== DeclarationKind::PositionalFormalParameter
||
69 kind
== DeclarationKind::FormalParameter
;
72 bool UsedNameTracker::noteUse(FrontendContext
* fc
, TaggedParserAtomIndex name
,
73 NameVisibility visibility
, uint32_t scriptId
,
75 mozilla::Maybe
<TokenPos
> tokenPosition
) {
76 if (UsedNameMap::AddPtr p
= map_
.lookupForAdd(name
)) {
77 p
->value().maybeUpdatePos(tokenPosition
);
79 if (!p
->value().noteUsedInScope(scriptId
, scopeId
)) {
83 // We need a token position precisely where we have private visibility.
84 MOZ_ASSERT(tokenPosition
.isSome() ==
85 (visibility
== NameVisibility::Private
));
87 if (visibility
== NameVisibility::Private
) {
88 // We have seen at least one private name
89 hasPrivateNames_
= true;
92 UsedNameInfo
info(fc
, visibility
, tokenPosition
);
94 if (!info
.noteUsedInScope(scriptId
, scopeId
)) {
97 if (!map_
.add(p
, name
, std::move(info
))) {
105 bool UsedNameTracker::getUnboundPrivateNames(
106 Vector
<UnboundPrivateName
, 8>& unboundPrivateNames
) {
107 // We never saw any private names, so can just return early
108 if (!hasPrivateNames_
) {
112 for (auto iter
= map_
.iter(); !iter
.done(); iter
.next()) {
113 // Don't care about public;
114 if (iter
.get().value().isPublic()) {
118 // empty list means all bound
119 if (iter
.get().value().empty()) {
123 if (!unboundPrivateNames
.emplaceBack(iter
.get().key(),
124 *iter
.get().value().pos())) {
129 // Return a sorted list in ascendng order of position.
130 auto comparePosition
= [](const auto& a
, const auto& b
) {
131 return a
.position
< b
.position
;
133 std::sort(unboundPrivateNames
.begin(), unboundPrivateNames
.end(),
139 bool UsedNameTracker::hasUnboundPrivateNames(
140 FrontendContext
* fc
, mozilla::Maybe
<UnboundPrivateName
>& maybeUnboundName
) {
141 // We never saw any private names, so can just return early
142 if (!hasPrivateNames_
) {
146 Vector
<UnboundPrivateName
, 8> unboundPrivateNames(fc
);
147 if (!getUnboundPrivateNames(unboundPrivateNames
)) {
151 if (unboundPrivateNames
.empty()) {
155 // GetUnboundPrivateNames returns the list sorted.
156 maybeUnboundName
.emplace(unboundPrivateNames
[0]);
160 void UsedNameTracker::UsedNameInfo::resetToScope(uint32_t scriptId
,
162 while (!uses_
.empty()) {
163 Use
& innermost
= uses_
.back();
164 if (innermost
.scopeId
< scopeId
) {
167 MOZ_ASSERT(innermost
.scriptId
>= scriptId
);
172 void UsedNameTracker::rewind(RewindToken token
) {
173 scriptCounter_
= token
.scriptId
;
174 scopeCounter_
= token
.scopeId
;
176 for (UsedNameMap::Range r
= map_
.all(); !r
.empty(); r
.popFront()) {
177 r
.front().value().resetToScope(token
.scriptId
, token
.scopeId
);
181 #if defined(DEBUG) || defined(JS_JITSPEW)
182 void UsedNameTracker::dump(ParserAtomsTable
& table
) {
183 js::Fprinter
out(stderr
);
185 out
.printf("Used names:\n");
187 for (UsedNameMap::Range r
= map_
.all(); !r
.empty(); r
.popFront()) {
188 const auto& item
= r
.front();
190 const auto& name
= item
.key();
191 const auto& nameInfo
= item
.value();
194 table
.dumpCharsNoQuote(out
, name
);
197 if (nameInfo
.visibility_
== NameVisibility::Private
) {
198 out
.put(" visibility: private\n");
201 if (nameInfo
.firstUsePos_
) {
202 const auto& pos
= *nameInfo
.firstUsePos_
;
203 out
.printf(" first use pos: %u\n", pos
.begin
);
206 out
.printf(" %zu user(s)", nameInfo
.uses_
.length());
208 for (const auto& use
: nameInfo
.uses_
) {
215 out
.printf("%u/%u", use
.scriptId
, use
.scopeId
);
225 void ParseContext::Scope::dump(ParseContext
* pc
, ParserBase
* parser
) {
226 fprintf(stdout
, "ParseScope %p", this);
228 fprintf(stdout
, "\n decls:\n");
229 for (DeclaredNameMap::Range r
= declared_
->all(); !r
.empty(); r
.popFront()) {
230 auto index
= r
.front().key();
231 UniqueChars bytes
= parser
->parserAtoms().toPrintableString(index
);
233 ReportOutOfMemory(pc
->sc()->fc_
);
236 DeclaredNameInfo
& info
= r
.front().value().wrapped
;
237 fprintf(stdout
, " %s %s%s\n", DeclarationKindString(info
.kind()),
238 bytes
.get(), info
.closedOver() ? " (closed over)" : "");
241 fprintf(stdout
, "\n");
244 bool ParseContext::Scope::addPossibleAnnexBFunctionBox(ParseContext
* pc
,
245 FunctionBox
* funbox
) {
246 if (!possibleAnnexBFunctionBoxes_
) {
247 if (!possibleAnnexBFunctionBoxes_
.acquire(pc
->sc()->fc_
)) {
252 return maybeReportOOM(pc
, possibleAnnexBFunctionBoxes_
->append(funbox
));
255 bool ParseContext::Scope::propagateAndMarkAnnexBFunctionBoxes(
256 ParseContext
* pc
, ParserBase
* parser
) {
257 // Strict mode doesn't have wack Annex B function semantics.
258 if (pc
->sc()->strict() || !possibleAnnexBFunctionBoxes_
||
259 possibleAnnexBFunctionBoxes_
->empty()) {
263 if (this == &pc
->varScope()) {
264 // Base case: actually declare the Annex B vars and mark applicable
265 // function boxes as Annex B.
266 Maybe
<DeclarationKind
> redeclaredKind
;
268 for (FunctionBox
* funbox
: *possibleAnnexBFunctionBoxes_
) {
270 if (!pc
->computeAnnexBAppliesToLexicalFunctionInInnermostScope(
271 funbox
, parser
, &annexBApplies
)) {
275 if (!pc
->tryDeclareVar(funbox
->explicitName(), parser
,
276 DeclarationKind::VarForAnnexBLexicalFunction
,
277 DeclaredNameInfo::npos
, &redeclaredKind
,
282 MOZ_ASSERT(!redeclaredKind
);
283 funbox
->isAnnexB
= true;
287 // Inner scope case: propagate still applicable function boxes to the
289 for (FunctionBox
* funbox
: *possibleAnnexBFunctionBoxes_
) {
291 if (!pc
->computeAnnexBAppliesToLexicalFunctionInInnermostScope(
292 funbox
, parser
, &annexBApplies
)) {
296 if (!enclosing()->addPossibleAnnexBFunctionBox(pc
, funbox
)) {
306 static bool DeclarationKindIsCatchParameter(DeclarationKind kind
) {
307 return kind
== DeclarationKind::SimpleCatchParameter
||
308 kind
== DeclarationKind::CatchParameter
;
311 bool ParseContext::Scope::addCatchParameters(ParseContext
* pc
,
312 Scope
& catchParamScope
) {
313 if (pc
->useAsmOrInsideUseAsm()) {
317 for (DeclaredNameMap::Range r
= catchParamScope
.declared_
->all(); !r
.empty();
319 DeclarationKind kind
= r
.front().value()->kind();
320 uint32_t pos
= r
.front().value()->pos();
321 MOZ_ASSERT(DeclarationKindIsCatchParameter(kind
));
322 auto name
= r
.front().key();
323 AddDeclaredNamePtr p
= lookupDeclaredNameForAdd(name
);
325 if (!addDeclaredName(pc
, p
, name
, kind
, pos
)) {
333 void ParseContext::Scope::removeCatchParameters(ParseContext
* pc
,
334 Scope
& catchParamScope
) {
335 if (pc
->useAsmOrInsideUseAsm()) {
339 for (DeclaredNameMap::Range r
= catchParamScope
.declared_
->all(); !r
.empty();
341 auto name
= r
.front().key();
342 DeclaredNamePtr p
= declared_
->lookup(name
);
345 // This check is needed because the catch body could have declared
346 // vars, which would have been added to catchParamScope.
347 if (DeclarationKindIsCatchParameter(r
.front().value()->kind())) {
348 declared_
->remove(p
);
353 ParseContext::ParseContext(FrontendContext
* fc
, ParseContext
*& parent
,
354 SharedContext
* sc
, ErrorReporter
& errorReporter
,
355 CompilationState
& compilationState
,
356 Directives
* newDirectives
, bool isFull
)
357 : Nestable
<ParseContext
>(&parent
),
359 errorReporter_(errorReporter
),
360 innermostStatement_(nullptr),
361 innermostScope_(nullptr),
363 positionalFormalParameterNames_(fc
->nameCollectionPool()),
364 closedOverBindingsForLazy_(fc
->nameCollectionPool()),
365 innerFunctionIndexesForLazy(sc
->fc_
),
366 newDirectives(newDirectives
),
367 lastYieldOffset(NoYieldOffset
),
368 lastAwaitOffset(NoAwaitOffset
),
369 scriptId_(compilationState
.usedNames
.nextScriptId()),
370 superScopeNeedsHomeObject_(false) {
371 if (isFunctionBox()) {
372 if (functionBox()->isNamedLambda()) {
373 namedLambdaScope_
.emplace(fc
, parent
, compilationState
.usedNames
);
375 functionScope_
.emplace(fc
, parent
, compilationState
.usedNames
);
379 bool ParseContext::init() {
380 if (scriptId_
== UINT32_MAX
) {
381 errorReporter_
.errorNoOffset(JSMSG_NEED_DIET
, "script");
385 FrontendContext
* fc
= sc()->fc_
;
387 if (isFunctionBox()) {
388 // Named lambdas always need a binding for their own name. If this
389 // binding is closed over when we finish parsing the function iNn
390 // finishFunctionScopes, the function box needs to be marked as
391 // needing a dynamic DeclEnv object.
392 if (functionBox()->isNamedLambda()) {
393 if (!namedLambdaScope_
->init(this)) {
396 AddDeclaredNamePtr p
= namedLambdaScope_
->lookupDeclaredNameForAdd(
397 functionBox()->explicitName());
399 if (!namedLambdaScope_
->addDeclaredName(
400 this, p
, functionBox()->explicitName(), DeclarationKind::Const
,
401 DeclaredNameInfo::npos
)) {
406 if (!functionScope_
->init(this)) {
410 if (!positionalFormalParameterNames_
.acquire(fc
)) {
415 if (!closedOverBindingsForLazy_
.acquire(fc
)) {
422 bool ParseContext::computeAnnexBAppliesToLexicalFunctionInInnermostScope(
423 FunctionBox
* funbox
, ParserBase
* parser
, bool* annexBApplies
) {
424 MOZ_ASSERT(!sc()->strict());
426 TaggedParserAtomIndex name
= funbox
->explicitName();
427 Maybe
<DeclarationKind
> redeclaredKind
;
428 if (!isVarRedeclaredInInnermostScope(
429 name
, parser
, DeclarationKind::VarForAnnexBLexicalFunction
,
434 if (!redeclaredKind
&& isFunctionBox()) {
435 Scope
& funScope
= functionScope();
436 if (&funScope
!= &varScope()) {
437 // Annex B.3.3.1 disallows redeclaring parameter names. In the
438 // presence of parameter expressions, parameter names are on the
439 // function scope, which encloses the var scope. This means the
440 // isVarRedeclaredInInnermostScope call above would not catch this
441 // case, so test it manually.
442 if (DeclaredNamePtr p
= funScope
.lookupDeclaredName(name
)) {
443 DeclarationKind declaredKind
= p
->value()->kind();
444 if (DeclarationKindIsParameter(declaredKind
)) {
445 redeclaredKind
= Some(declaredKind
);
447 MOZ_ASSERT(FunctionScope::isSpecialName(name
));
453 // If an early error would have occurred already, this function should not
454 // exhibit Annex B.3.3 semantics.
455 *annexBApplies
= !redeclaredKind
;
459 bool ParseContext::isVarRedeclaredInInnermostScope(
460 TaggedParserAtomIndex name
, ParserBase
* parser
, DeclarationKind kind
,
461 mozilla::Maybe
<DeclarationKind
>* out
) {
463 return tryDeclareVarHelper
<DryRunInnermostScopeOnly
>(
464 name
, parser
, kind
, DeclaredNameInfo::npos
, out
, &unused
);
467 bool ParseContext::isVarRedeclaredInEval(TaggedParserAtomIndex name
,
469 DeclarationKind kind
,
470 Maybe
<DeclarationKind
>* out
) {
471 auto maybeKind
= parser
->getCompilationState()
472 .scopeContext
.lookupLexicalBindingInEnclosingScope(name
);
478 switch (*maybeKind
) {
479 case ScopeContext::EnclosingLexicalBindingKind::Let
:
480 *out
= Some(DeclarationKind::Let
);
482 case ScopeContext::EnclosingLexicalBindingKind::Const
:
483 *out
= Some(DeclarationKind::Const
);
485 case ScopeContext::EnclosingLexicalBindingKind::CatchParameter
:
486 *out
= Some(DeclarationKind::CatchParameter
);
488 case ScopeContext::EnclosingLexicalBindingKind::Synthetic
:
489 *out
= Some(DeclarationKind::Synthetic
);
491 case ScopeContext::EnclosingLexicalBindingKind::PrivateMethod
:
492 *out
= Some(DeclarationKind::PrivateMethod
);
498 bool ParseContext::tryDeclareVar(TaggedParserAtomIndex name
, ParserBase
* parser
,
499 DeclarationKind kind
, uint32_t beginPos
,
500 Maybe
<DeclarationKind
>* redeclaredKind
,
502 return tryDeclareVarHelper
<NotDryRun
>(name
, parser
, kind
, beginPos
,
503 redeclaredKind
, prevPos
);
506 template <ParseContext::DryRunOption dryRunOption
>
507 bool ParseContext::tryDeclareVarHelper(TaggedParserAtomIndex name
,
508 ParserBase
* parser
, DeclarationKind kind
,
510 Maybe
<DeclarationKind
>* redeclaredKind
,
512 MOZ_ASSERT(DeclarationKindIsVar(kind
));
514 // It is an early error if a 'var' declaration appears inside a
515 // scope contour that has a lexical declaration of the same name. For
516 // example, the following are early errors:
519 // { { var x; } let x; }
521 // And the following are not:
524 // { { let x; } var x; }
526 for (ParseContext::Scope
* scope
= innermostScope();
527 scope
!= varScope().enclosing(); scope
= scope
->enclosing()) {
528 if (AddDeclaredNamePtr p
= scope
->lookupDeclaredNameForAdd(name
)) {
529 DeclarationKind declaredKind
= p
->value()->kind();
530 if (DeclarationKindIsVar(declaredKind
)) {
531 if (dryRunOption
== NotDryRun
) {
532 RedeclareVar(p
, kind
);
534 } else if (!DeclarationKindIsParameter(declaredKind
)) {
535 // Annex B.3.5 allows redeclaring simple (non-destructured)
536 // catch parameters with var declarations.
537 bool annexB35Allowance
=
538 declaredKind
== DeclarationKind::SimpleCatchParameter
;
540 // Annex B.3.3 allows redeclaring functions in the same block.
541 bool annexB33Allowance
=
542 declaredKind
== DeclarationKind::SloppyLexicalFunction
&&
543 kind
== DeclarationKind::VarForAnnexBLexicalFunction
&&
544 scope
== innermostScope();
546 if (!annexB35Allowance
&& !annexB33Allowance
) {
547 *redeclaredKind
= Some(declaredKind
);
548 *prevPos
= p
->value()->pos();
551 } else if (kind
== DeclarationKind::VarForAnnexBLexicalFunction
) {
552 MOZ_ASSERT(DeclarationKindIsParameter(declaredKind
));
554 // Annex B.3.3.1 disallows redeclaring parameter names.
555 // We don't need to set *prevPos here since this case is not
557 *redeclaredKind
= Some(declaredKind
);
560 } else if (dryRunOption
== NotDryRun
) {
561 if (!scope
->addDeclaredName(this, p
, name
, kind
, beginPos
)) {
566 // DryRunOption is used for propagating Annex B functions: we don't
567 // want to declare the synthesized Annex B vars until we exit the var
568 // scope and know that no early errors would have occurred. In order
569 // to avoid quadratic search, we only check for var redeclarations in
570 // the innermost scope when doing a dry run.
571 if (dryRunOption
== DryRunInnermostScopeOnly
) {
576 if (!sc()->strict() && sc()->isEvalContext() &&
577 (dryRunOption
== NotDryRun
|| innermostScope() == &varScope())) {
578 if (!isVarRedeclaredInEval(name
, parser
, kind
, redeclaredKind
)) {
581 // We don't have position information at runtime.
582 *prevPos
= DeclaredNameInfo::npos
;
588 bool ParseContext::hasUsedName(const UsedNameTracker
& usedNames
,
589 TaggedParserAtomIndex name
) {
590 if (auto p
= usedNames
.lookup(name
)) {
591 return p
->value().isUsedInScript(scriptId());
596 bool ParseContext::hasUsedFunctionSpecialName(const UsedNameTracker
& usedNames
,
597 TaggedParserAtomIndex name
) {
598 MOZ_ASSERT(name
== TaggedParserAtomIndex::WellKnown::arguments() ||
599 name
== TaggedParserAtomIndex::WellKnown::dot_this_() ||
600 name
== TaggedParserAtomIndex::WellKnown::dot_newTarget_());
601 return hasUsedName(usedNames
, name
) ||
602 functionBox()->bindingsAccessedDynamically();
605 bool ParseContext::declareFunctionThis(const UsedNameTracker
& usedNames
,
606 bool canSkipLazyClosedOverBindings
) {
607 // The asm.js validator does all its own symbol-table management so, as an
608 // optimization, avoid doing any work here.
609 if (useAsmOrInsideUseAsm()) {
613 // Derived class constructors emit JSOp::CheckReturn, which requires
614 // '.this' to be bound. Class field initializers implicitly read `.this`.
615 // Therefore we unconditionally declare `.this` in all class constructors.
616 FunctionBox
* funbox
= functionBox();
617 auto dotThis
= TaggedParserAtomIndex::WellKnown::dot_this_();
620 if (canSkipLazyClosedOverBindings
) {
621 declareThis
= funbox
->functionHasThisBinding();
623 declareThis
= hasUsedFunctionSpecialName(usedNames
, dotThis
) ||
624 funbox
->isClassConstructor();
628 ParseContext::Scope
& funScope
= functionScope();
629 AddDeclaredNamePtr p
= funScope
.lookupDeclaredNameForAdd(dotThis
);
631 if (!funScope
.addDeclaredName(this, p
, dotThis
, DeclarationKind::Var
,
632 DeclaredNameInfo::npos
)) {
635 funbox
->setFunctionHasThisBinding();
641 bool ParseContext::declareFunctionArgumentsObject(
642 const UsedNameTracker
& usedNames
, bool canSkipLazyClosedOverBindings
) {
643 FunctionBox
* funbox
= functionBox();
644 ParseContext::Scope
& funScope
= functionScope();
645 ParseContext::Scope
& _varScope
= varScope();
647 bool usesArguments
= false;
648 bool hasExtraBodyVarScope
= &funScope
!= &_varScope
;
650 // Time to implement the odd semantics of 'arguments'.
651 auto argumentsName
= TaggedParserAtomIndex::WellKnown::arguments();
653 bool tryDeclareArguments
;
654 if (canSkipLazyClosedOverBindings
) {
655 tryDeclareArguments
= funbox
->shouldDeclareArguments();
657 tryDeclareArguments
= hasUsedFunctionSpecialName(usedNames
, argumentsName
);
660 // ES 9.2.12 steps 19 and 20 say formal parameters, lexical bindings,
661 // and body-level functions named 'arguments' shadow the arguments
664 // So even if there wasn't a free use of 'arguments' but there is a var
665 // binding of 'arguments', we still might need the arguments object.
667 // If we have an extra var scope due to parameter expressions and the body
668 // declared 'var arguments', we still need to declare 'arguments' in the
670 DeclaredNamePtr p
= _varScope
.lookupDeclaredName(argumentsName
);
671 if (p
&& p
->value()->kind() == DeclarationKind::Var
) {
672 if (hasExtraBodyVarScope
) {
673 tryDeclareArguments
= true;
675 usesArguments
= true;
679 if (tryDeclareArguments
) {
680 AddDeclaredNamePtr p
= funScope
.lookupDeclaredNameForAdd(argumentsName
);
682 if (!funScope
.addDeclaredName(this, p
, argumentsName
,
683 DeclarationKind::Var
,
684 DeclaredNameInfo::npos
)) {
687 funbox
->setShouldDeclareArguments();
688 usesArguments
= true;
689 } else if (hasExtraBodyVarScope
) {
690 // Formal parameters shadow the arguments object.
696 funbox
->setNeedsArgsObj();
702 bool ParseContext::declareNewTarget(const UsedNameTracker
& usedNames
,
703 bool canSkipLazyClosedOverBindings
) {
704 // The asm.js validator does all its own symbol-table management so, as an
705 // optimization, avoid doing any work here.
706 if (useAsmOrInsideUseAsm()) {
710 FunctionBox
* funbox
= functionBox();
711 auto dotNewTarget
= TaggedParserAtomIndex::WellKnown::dot_newTarget_();
713 bool declareNewTarget
;
714 if (canSkipLazyClosedOverBindings
) {
715 declareNewTarget
= funbox
->functionHasNewTargetBinding();
717 declareNewTarget
= hasUsedFunctionSpecialName(usedNames
, dotNewTarget
);
720 if (declareNewTarget
) {
721 ParseContext::Scope
& funScope
= functionScope();
722 AddDeclaredNamePtr p
= funScope
.lookupDeclaredNameForAdd(dotNewTarget
);
724 if (!funScope
.addDeclaredName(this, p
, dotNewTarget
, DeclarationKind::Var
,
725 DeclaredNameInfo::npos
)) {
728 funbox
->setFunctionHasNewTargetBinding();
734 bool ParseContext::declareDotGeneratorName() {
735 // The special '.generator' binding must be on the function scope, and must
736 // be marked closed-over, as generators expect to find it on the CallObject.
737 ParseContext::Scope
& funScope
= functionScope();
738 auto dotGenerator
= TaggedParserAtomIndex::WellKnown::dot_generator_();
739 AddDeclaredNamePtr p
= funScope
.lookupDeclaredNameForAdd(dotGenerator
);
741 if (!funScope
.addDeclaredName(this, p
, dotGenerator
, DeclarationKind::Var
,
742 DeclaredNameInfo::npos
, ClosedOver::Yes
)) {
749 bool ParseContext::declareTopLevelDotGeneratorName() {
750 // Provide a .generator binding on the module scope for compatibility with
751 // generator code, which expect to find it on the CallObject for normal
754 sc()->isModuleContext(),
755 "Tried to declare top level dot generator in a non-module context.");
756 ParseContext::Scope
& modScope
= varScope();
757 auto dotGenerator
= TaggedParserAtomIndex::WellKnown::dot_generator_();
758 AddDeclaredNamePtr p
= modScope
.lookupDeclaredNameForAdd(dotGenerator
);
760 modScope
.addDeclaredName(this, p
, dotGenerator
, DeclarationKind::Var
,
761 DeclaredNameInfo::npos
, ClosedOver::Yes
);
764 } // namespace frontend