• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_AST_SCOPES_H_
6 #define V8_AST_SCOPES_H_
7 
8 #include <numeric>
9 
10 #include "src/ast/ast.h"
11 #include "src/base/compiler-specific.h"
12 #include "src/base/hashmap.h"
13 #include "src/base/threaded-list.h"
14 #include "src/common/globals.h"
15 #include "src/objects/function-kind.h"
16 #include "src/objects/objects.h"
17 #include "src/utils/pointer-with-payload.h"
18 #include "src/utils/utils.h"
19 #include "src/zone/zone-hashmap.h"
20 #include "src/zone/zone.h"
21 
22 namespace v8 {
23 namespace internal {
24 
25 class AstNodeFactory;
26 class AstValueFactory;
27 class AstRawString;
28 class Declaration;
29 class ParseInfo;
30 class Parser;
31 class PreparseDataBuilder;
32 class SloppyBlockFunctionStatement;
33 class Statement;
34 class StringSet;
35 class VariableProxy;
36 
37 using UnresolvedList =
38     base::ThreadedList<VariableProxy, VariableProxy::UnresolvedNext>;
39 
40 // A hash map to support fast variable declaration and lookup.
41 class VariableMap : public ZoneHashMap {
42  public:
43   explicit VariableMap(Zone* zone);
44   VariableMap(const VariableMap& other, Zone* zone);
45 
VariableMap(VariableMap && other)46   VariableMap(VariableMap&& other) V8_NOEXCEPT : ZoneHashMap(std::move(other)) {
47   }
48 
49   VariableMap& operator=(VariableMap&& other) V8_NOEXCEPT {
50     static_cast<ZoneHashMap&>(*this) = std::move(other);
51     return *this;
52   }
53 
54   Variable* Declare(Zone* zone, Scope* scope, const AstRawString* name,
55                     VariableMode mode, VariableKind kind,
56                     InitializationFlag initialization_flag,
57                     MaybeAssignedFlag maybe_assigned_flag,
58                     IsStaticFlag is_static_flag, bool* was_added);
59 
60   V8_EXPORT_PRIVATE Variable* Lookup(const AstRawString* name);
61   void Remove(Variable* var);
62   void Add(Variable* var);
63 
zone()64   Zone* zone() const { return allocator().zone(); }
65 };
66 
67 class Scope;
68 
69 template <>
70 struct PointerWithPayloadTraits<Scope> {
71   static constexpr int value = 1;
72 };
73 
74 // Global invariants after AST construction: Each reference (i.e. identifier)
75 // to a JavaScript variable (including global properties) is represented by a
76 // VariableProxy node. Immediately after AST construction and before variable
77 // allocation, most VariableProxy nodes are "unresolved", i.e. not bound to a
78 // corresponding variable (though some are bound during parse time). Variable
79 // allocation binds each unresolved VariableProxy to one Variable and assigns
80 // a location. Note that many VariableProxy nodes may refer to the same Java-
81 // Script variable.
82 
83 // JS environments are represented in the parser using Scope, DeclarationScope
84 // and ModuleScope. DeclarationScope is used for any scope that hosts 'var'
85 // declarations. This includes script, module, eval, varblock, and function
86 // scope. ModuleScope further specializes DeclarationScope.
87 class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
88  public:
89   // ---------------------------------------------------------------------------
90   // Construction
91 
92   Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type);
93 
94 #ifdef DEBUG
95   // The scope name is only used for printing/debugging.
96   void SetScopeName(const AstRawString* scope_name) {
97     scope_name_ = scope_name;
98   }
99 #endif
100 
101   DeclarationScope* AsDeclarationScope();
102   const DeclarationScope* AsDeclarationScope() const;
103   ModuleScope* AsModuleScope();
104   const ModuleScope* AsModuleScope() const;
105   ClassScope* AsClassScope();
106   const ClassScope* AsClassScope() const;
107 
108   class Snapshot final {
109    public:
110     Snapshot()
111         : outer_scope_and_calls_eval_(nullptr, false),
112           top_unresolved_(),
113           top_local_() {
114       DCHECK(IsCleared());
115     }
116     inline explicit Snapshot(Scope* scope);
117 
118     // Disallow copy and move.
119     Snapshot(const Snapshot&) = delete;
120     Snapshot(Snapshot&&) = delete;
121 
122     ~Snapshot() {
123       // If we're still active, there was no arrow function. In that case outer
124       // calls eval if it already called eval before this snapshot started, or
125       // if the code during the snapshot called eval.
126       if (!IsCleared() && outer_scope_and_calls_eval_.GetPayload()) {
127         RestoreEvalFlag();
128       }
129     }
130 
131     void RestoreEvalFlag() {
132       if (outer_scope_and_calls_eval_.GetPayload()) {
133         // This recreates both calls_eval and sloppy_eval_can_extend_vars.
134         outer_scope_and_calls_eval_.GetPointer()->RecordEvalCall();
135       }
136     }
137 
138     void Reparent(DeclarationScope* new_parent);
139     bool IsCleared() const {
140       return outer_scope_and_calls_eval_.GetPointer() == nullptr;
141     }
142 
143     void Clear() {
144       outer_scope_and_calls_eval_.SetPointer(nullptr);
145 #ifdef DEBUG
146       outer_scope_and_calls_eval_.SetPayload(false);
147       top_inner_scope_ = nullptr;
148       top_local_ = base::ThreadedList<Variable>::Iterator();
149       top_unresolved_ = UnresolvedList::Iterator();
150 #endif
151     }
152 
153    private:
154     // During tracking calls_eval caches whether the outer scope called eval.
155     // Upon move assignment we store whether the new inner scope calls eval into
156     // the move target calls_eval bit, and restore calls eval on the outer
157     // scope.
158     PointerWithPayload<Scope, bool, 1> outer_scope_and_calls_eval_;
159     Scope* top_inner_scope_;
160     UnresolvedList::Iterator top_unresolved_;
161     base::ThreadedList<Variable>::Iterator top_local_;
162   };
163 
164   enum class DeserializationMode { kIncludingVariables, kScopesOnly };
165 
166   static Scope* DeserializeScopeChain(Isolate* isolate, Zone* zone,
167                                       ScopeInfo scope_info,
168                                       DeclarationScope* script_scope,
169                                       AstValueFactory* ast_value_factory,
170                                       DeserializationMode deserialization_mode);
171 
172   // Checks if the block scope is redundant, i.e. it does not contain any
173   // block scoped declarations. In that case it is removed from the scope
174   // tree and its children are reparented.
175   Scope* FinalizeBlockScope();
176 
177   // Inserts outer_scope into this scope's scope chain (and removes this
178   // from the current outer_scope_'s inner scope list).
179   // Assumes outer_scope_ is non-null.
180   void ReplaceOuterScope(Scope* outer_scope);
181 
182   Zone* zone() const { return variables_.zone(); }
183 
184   void SetMustUsePreparseData() {
185     if (must_use_preparsed_scope_data_) {
186       return;
187     }
188     must_use_preparsed_scope_data_ = true;
189     if (outer_scope_) {
190       outer_scope_->SetMustUsePreparseData();
191     }
192   }
193 
194   bool must_use_preparsed_scope_data() const {
195     return must_use_preparsed_scope_data_;
196   }
197 
198   // ---------------------------------------------------------------------------
199   // Declarations
200 
201   // Lookup a variable in this scope. Returns the variable or nullptr if not
202   // found.
203   Variable* LookupLocal(const AstRawString* name) {
204     DCHECK(scope_info_.is_null());
205     return variables_.Lookup(name);
206   }
207 
208   Variable* LookupInScopeInfo(const AstRawString* name, Scope* cache);
209 
210   // Declare a local variable in this scope. If the variable has been
211   // declared before, the previously declared variable is returned.
212   Variable* DeclareLocal(const AstRawString* name, VariableMode mode,
213                          VariableKind kind, bool* was_added,
214                          InitializationFlag init_flag = kCreatedInitialized);
215 
216   Variable* DeclareVariable(Declaration* declaration, const AstRawString* name,
217                             int pos, VariableMode mode, VariableKind kind,
218                             InitializationFlag init, bool* was_added,
219                             bool* sloppy_mode_block_scope_function_redefinition,
220                             bool* ok);
221 
222   // Returns nullptr if there was a declaration conflict.
223   Variable* DeclareVariableName(const AstRawString* name, VariableMode mode,
224                                 bool* was_added,
225                                 VariableKind kind = NORMAL_VARIABLE);
226   Variable* DeclareCatchVariableName(const AstRawString* name);
227 
228   // Declarations list.
229   base::ThreadedList<Declaration>* declarations() { return &decls_; }
230 
231   base::ThreadedList<Variable>* locals() { return &locals_; }
232 
233   // Create a new unresolved variable.
234   VariableProxy* NewUnresolved(AstNodeFactory* factory,
235                                const AstRawString* name, int start_pos,
236                                VariableKind kind = NORMAL_VARIABLE) {
237     // Note that we must not share the unresolved variables with
238     // the same name because they may be removed selectively via
239     // RemoveUnresolved().
240     DCHECK(!already_resolved_);
241     DCHECK_EQ(factory->zone(), zone());
242     VariableProxy* proxy = factory->NewVariableProxy(name, kind, start_pos);
243     AddUnresolved(proxy);
244     return proxy;
245   }
246 
247   void AddUnresolved(VariableProxy* proxy);
248 
249   // Removes an unresolved variable from the list so it can be readded to
250   // another list. This is used to reparent parameter initializers that contain
251   // sloppy eval.
252   bool RemoveUnresolved(VariableProxy* var);
253 
254   // Deletes an unresolved variable. The variable proxy cannot be reused for
255   // another list later. During parsing, an unresolved variable may have been
256   // added optimistically, but then only the variable name was used (typically
257   // for labels and arrow function parameters). If the variable was not
258   // declared, the addition introduced a new unresolved variable which may end
259   // up being allocated globally as a "ghost" variable. DeleteUnresolved removes
260   // such a variable again if it was added; otherwise this is a no-op.
261   void DeleteUnresolved(VariableProxy* var);
262 
263   // Creates a new temporary variable in this scope's TemporaryScope.  The
264   // name is only used for printing and cannot be used to find the variable.
265   // In particular, the only way to get hold of the temporary is by keeping the
266   // Variable* around.  The name should not clash with a legitimate variable
267   // names.
268   // TODO(verwaest): Move to DeclarationScope?
269   Variable* NewTemporary(const AstRawString* name);
270 
271   // Find variable with (variable->mode() <= |mode_limit|) that was declared in
272   // |scope|. This is used to catch patterns like `try{}catch(e){let e;}` and
273   // function([e]) { let e }, which are errors even though the two 'e's are each
274   // time declared in different scopes. Returns the first duplicate variable
275   // name if there is one, nullptr otherwise.
276   const AstRawString* FindVariableDeclaredIn(Scope* scope,
277                                              VariableMode mode_limit);
278 
279   // ---------------------------------------------------------------------------
280   // Scope-specific info.
281 
282   // Inform the scope and outer scopes that the corresponding code contains an
283   // eval call.
284   inline void RecordEvalCall();
285 
286   void RecordInnerScopeEvalCall() {
287     inner_scope_calls_eval_ = true;
288     for (Scope* scope = outer_scope(); scope != nullptr;
289          scope = scope->outer_scope()) {
290       if (scope->inner_scope_calls_eval_) return;
291       scope->inner_scope_calls_eval_ = true;
292     }
293   }
294 
295   // Set the language mode flag (unless disabled by a global flag).
296   void SetLanguageMode(LanguageMode language_mode) {
297     DCHECK(!is_module_scope() || is_strict(language_mode));
298     set_language_mode(language_mode);
299   }
300 
301   // Inform the scope that the scope may execute declarations nonlinearly.
302   // Currently, the only nonlinear scope is a switch statement. The name is
303   // more general in case something else comes up with similar control flow,
304   // for example the ability to break out of something which does not have
305   // its own lexical scope.
306   // The bit does not need to be stored on the ScopeInfo because none of
307   // the three compilers will perform hole check elimination on a variable
308   // located in VariableLocation::CONTEXT. So, direct eval and closures
309   // will not expose holes.
310   void SetNonlinear() { scope_nonlinear_ = true; }
311 
312   // Position in the source where this scope begins and ends.
313   //
314   // * For the scope of a with statement
315   //     with (obj) stmt
316   //   start position: start position of first token of 'stmt'
317   //   end position: end position of last token of 'stmt'
318   // * For the scope of a block
319   //     { stmts }
320   //   start position: start position of '{'
321   //   end position: end position of '}'
322   // * For the scope of a function literal or decalaration
323   //     function fun(a,b) { stmts }
324   //   start position: start position of '('
325   //   end position: end position of '}'
326   // * For the scope of a catch block
327   //     try { stms } catch(e) { stmts }
328   //   start position: start position of '('
329   //   end position: end position of ')'
330   // * For the scope of a for-statement
331   //     for (let x ...) stmt
332   //   start position: start position of '('
333   //   end position: end position of last token of 'stmt'
334   // * For the scope of a switch statement
335   //     switch (tag) { cases }
336   //   start position: start position of '{'
337   //   end position: end position of '}'
338   int start_position() const { return start_position_; }
339   void set_start_position(int statement_pos) {
340     start_position_ = statement_pos;
341   }
342   int end_position() const { return end_position_; }
343   void set_end_position(int statement_pos) { end_position_ = statement_pos; }
344 
345   // Scopes created for desugaring are hidden. I.e. not visible to the debugger.
346   bool is_hidden() const { return is_hidden_; }
347   void set_is_hidden() { is_hidden_ = true; }
348 
349   void ForceContextAllocationForParameters() {
350     DCHECK(!already_resolved_);
351     force_context_allocation_for_parameters_ = true;
352   }
353   bool has_forced_context_allocation_for_parameters() const {
354     return force_context_allocation_for_parameters_;
355   }
356 
357   // ---------------------------------------------------------------------------
358   // Predicates.
359 
360   // Specific scope types.
361   bool is_eval_scope() const { return scope_type_ == EVAL_SCOPE; }
362   bool is_function_scope() const { return scope_type_ == FUNCTION_SCOPE; }
363   bool is_module_scope() const { return scope_type_ == MODULE_SCOPE; }
364   bool is_script_scope() const { return scope_type_ == SCRIPT_SCOPE; }
365   bool is_catch_scope() const { return scope_type_ == CATCH_SCOPE; }
366   bool is_block_scope() const {
367     return scope_type_ == BLOCK_SCOPE || scope_type_ == CLASS_SCOPE;
368   }
369   bool is_with_scope() const { return scope_type_ == WITH_SCOPE; }
370   bool is_declaration_scope() const { return is_declaration_scope_; }
371   bool is_class_scope() const { return scope_type_ == CLASS_SCOPE; }
372 
373   bool inner_scope_calls_eval() const { return inner_scope_calls_eval_; }
374   bool private_name_lookup_skips_outer_class() const {
375     return private_name_lookup_skips_outer_class_;
376   }
377   bool IsAsmModule() const;
378   // Returns true if this scope or any inner scopes that might be eagerly
379   // compiled are asm modules.
380   bool ContainsAsmModule() const;
381   // Does this scope have the potential to execute declarations non-linearly?
382   bool is_nonlinear() const { return scope_nonlinear_; }
383   // Returns if we need to force a context because the current scope is stricter
384   // than the outerscope. We need this to properly track the language mode using
385   // the context. This is required in ICs where we lookup the language mode
386   // from the context.
387   bool ForceContextForLanguageMode() const {
388     // For function scopes we need not force a context since the language mode
389     // can be obtained from the closure. Script scopes always have a context.
390     if (scope_type_ == FUNCTION_SCOPE || scope_type_ == SCRIPT_SCOPE) {
391       return false;
392     }
393     DCHECK_NOT_NULL(outer_scope_);
394     return (language_mode() > outer_scope_->language_mode());
395   }
396 
397   // Whether this needs to be represented by a runtime context.
398   bool NeedsContext() const {
399     // Catch scopes always have heap slots.
400     DCHECK_IMPLIES(is_catch_scope(), num_heap_slots() > 0);
401     DCHECK_IMPLIES(is_with_scope(), num_heap_slots() > 0);
402     DCHECK_IMPLIES(ForceContextForLanguageMode(), num_heap_slots() > 0);
403     return num_heap_slots() > 0;
404   }
405 
406   // Use Scope::ForEach for depth first traversal of scopes.
407   // Before:
408   // void Scope::VisitRecursively() {
409   //   DoSomething();
410   //   for (Scope* s = inner_scope_; s != nullptr; s = s->sibling_) {
411   //     if (s->ShouldContinue()) continue;
412   //     s->VisitRecursively();
413   //   }
414   // }
415   //
416   // After:
417   // void Scope::VisitIteratively() {
418   //   this->ForEach([](Scope* s) {
419   //      s->DoSomething();
420   //      return s->ShouldContinue() ? kContinue : kDescend;
421   //   });
422   // }
423   template <typename FunctionType>
424   V8_INLINE void ForEach(FunctionType callback);
425   enum Iteration {
426     // Continue the iteration on the same level, do not recurse/descent into
427     // inner scopes.
428     kContinue,
429     // Recurse/descend into inner scopes.
430     kDescend
431   };
432 
433   // Check is this scope is an outer scope of the given scope.
434   bool IsOuterScopeOf(Scope* other) const;
435 
436   // ---------------------------------------------------------------------------
437   // Accessors.
438 
439   // The type of this scope.
440   ScopeType scope_type() const { return scope_type_; }
441 
442   // The language mode of this scope.
443   LanguageMode language_mode() const {
444     return is_strict_ ? LanguageMode::kStrict : LanguageMode::kSloppy;
445   }
446 
447   // inner_scope() and sibling() together implement the inner scope list of a
448   // scope. Inner scope points to the an inner scope of the function, and
449   // "sibling" points to a next inner scope of the outer scope of this scope.
450   Scope* inner_scope() const { return inner_scope_; }
451   Scope* sibling() const { return sibling_; }
452 
453   // The scope immediately surrounding this scope, or nullptr.
454   Scope* outer_scope() const { return outer_scope_; }
455 
456   Variable* catch_variable() const {
457     DCHECK(is_catch_scope());
458     DCHECK_EQ(1, num_var());
459     return static_cast<Variable*>(variables_.Start()->value);
460   }
461 
462   bool ShouldBanArguments();
463 
464   // ---------------------------------------------------------------------------
465   // Variable allocation.
466 
467   // Result of variable allocation.
468   int num_stack_slots() const { return num_stack_slots_; }
469   int num_heap_slots() const { return num_heap_slots_; }
470 
471   bool HasContextExtensionSlot() const {
472     switch (scope_type_) {
473       case MODULE_SCOPE:
474       case WITH_SCOPE:  // DebugEvaluateContext as well
475         return true;
476       default:
477         DCHECK_IMPLIES(sloppy_eval_can_extend_vars_,
478                        scope_type_ == FUNCTION_SCOPE ||
479                            scope_type_ == EVAL_SCOPE ||
480                            scope_type_ == BLOCK_SCOPE);
481         DCHECK_IMPLIES(sloppy_eval_can_extend_vars_, is_declaration_scope());
482         return sloppy_eval_can_extend_vars_;
483     }
484     UNREACHABLE();
485   }
486   int ContextHeaderLength() const {
487     return HasContextExtensionSlot() ? Context::MIN_CONTEXT_EXTENDED_SLOTS
488                                      : Context::MIN_CONTEXT_SLOTS;
489   }
490 
491   int ContextLocalCount() const;
492 
493   // Determine if we can parse a function literal in this scope lazily without
494   // caring about the unresolved variables within.
495   bool AllowsLazyParsingWithoutUnresolvedVariables(const Scope* outer) const;
496 
497   // The number of contexts between this and scope; zero if this == scope.
498   int ContextChainLength(Scope* scope) const;
499 
500   // The number of contexts between this and the outermost context that has a
501   // sloppy eval call. One if this->sloppy_eval_can_extend_vars().
502   int ContextChainLengthUntilOutermostSloppyEval() const;
503 
504   // Find the first function, script, eval or (declaration) block scope. This is
505   // the scope where var declarations will be hoisted to in the implementation.
506   DeclarationScope* GetDeclarationScope();
507 
508   // Find the first function, script, or (declaration) block scope.
509   // This is the scope where var declarations will be hoisted to in the
510   // implementation, including vars in direct sloppy eval calls.
511   //
512   // TODO(leszeks): Check how often we skip eval scopes in GetDeclarationScope,
513   // and possibly merge this with GetDeclarationScope.
514   DeclarationScope* GetNonEvalDeclarationScope();
515 
516   // Find the first non-block declaration scope. This should be either a script,
517   // function, or eval scope. Same as DeclarationScope(), but skips declaration
518   // "block" scopes. Used for differentiating associated function objects (i.e.,
519   // the scope for which a function prologue allocates a context) or declaring
520   // temporaries.
521   DeclarationScope* GetClosureScope();
522   const DeclarationScope* GetClosureScope() const;
523 
524   // Find the first (non-arrow) function or script scope.  This is where
525   // 'this' is bound, and what determines the function kind.
526   DeclarationScope* GetReceiverScope();
527 
528   DeclarationScope* GetScriptScope();
529 
530   // Find the innermost outer scope that needs a context.
531   Scope* GetOuterScopeWithContext();
532 
533   bool HasThisReference() const;
534 
535   // Analyze() must have been called once to create the ScopeInfo.
536   Handle<ScopeInfo> scope_info() const {
537     DCHECK(!scope_info_.is_null());
538     return scope_info_;
539   }
540 
541   int num_var() const { return variables_.occupancy(); }
542 
543   // ---------------------------------------------------------------------------
544   // Debugging.
545 
546 #ifdef DEBUG
547   void Print(int n = 0);  // n = indentation; n < 0 => don't print recursively
548 
549   // Check that the scope has positions assigned.
550   void CheckScopePositions();
551 
552   // Check that all Scopes in the scope tree use the same Zone.
553   void CheckZones();
554 #endif
555 
556   // Retrieve `IsSimpleParameterList` of current or outer function.
557   bool HasSimpleParameters();
558   void set_is_debug_evaluate_scope() { is_debug_evaluate_scope_ = true; }
559   bool is_debug_evaluate_scope() const { return is_debug_evaluate_scope_; }
560   bool IsSkippableFunctionScope();
561   void set_is_repl_mode_scope() { is_repl_mode_scope_ = true; }
562   bool is_repl_mode_scope() const {
563     DCHECK_IMPLIES(is_repl_mode_scope_, is_script_scope());
564     return is_repl_mode_scope_;
565   }
566   void set_deserialized_scope_uses_external_cache() {
567     deserialized_scope_uses_external_cache_ = true;
568   }
569   bool deserialized_scope_uses_external_cache() const {
570     return deserialized_scope_uses_external_cache_;
571   }
572 
573   bool RemoveInnerScope(Scope* inner_scope) {
574     DCHECK_NOT_NULL(inner_scope);
575     if (inner_scope == inner_scope_) {
576       inner_scope_ = inner_scope_->sibling_;
577       return true;
578     }
579     for (Scope* scope = inner_scope_; scope != nullptr;
580          scope = scope->sibling_) {
581       if (scope->sibling_ == inner_scope) {
582         scope->sibling_ = scope->sibling_->sibling_;
583         return true;
584       }
585     }
586     return false;
587   }
588 
589   Variable* LookupInScopeOrScopeInfo(const AstRawString* name, Scope* cache) {
590     Variable* var = variables_.Lookup(name);
591     if (var != nullptr || scope_info_.is_null()) return var;
592     return LookupInScopeInfo(name, cache);
593   }
594 
595   Variable* LookupForTesting(const AstRawString* name) {
596     for (Scope* scope = this; scope != nullptr; scope = scope->outer_scope()) {
597       Variable* var = scope->LookupInScopeOrScopeInfo(name, scope);
598       if (var != nullptr) return var;
599     }
600     return nullptr;
601   }
602 
603  protected:
604   explicit Scope(Zone* zone);
605 
606   void set_language_mode(LanguageMode language_mode) {
607     is_strict_ = is_strict(language_mode);
608   }
609 
610  private:
611   Variable* Declare(Zone* zone, const AstRawString* name, VariableMode mode,
612                     VariableKind kind, InitializationFlag initialization_flag,
613                     MaybeAssignedFlag maybe_assigned_flag, bool* was_added) {
614     // Static variables can only be declared using ClassScope methods.
615     Variable* result = variables_.Declare(
616         zone, this, name, mode, kind, initialization_flag, maybe_assigned_flag,
617         IsStaticFlag::kNotStatic, was_added);
618     if (*was_added) locals_.Add(result);
619     return result;
620   }
621 
622   // This method should only be invoked on scopes created during parsing (i.e.,
623   // not deserialized from a context). Also, since NeedsContext() is only
624   // returning a valid result after variables are resolved, NeedsScopeInfo()
625   // should also be invoked after resolution.
626   bool NeedsScopeInfo() const;
627 
628   Variable* NewTemporary(const AstRawString* name,
629                          MaybeAssignedFlag maybe_assigned);
630 
631   // Walk the scope chain to find DeclarationScopes; call
632   // SavePreparseDataForDeclarationScope for each.
633   void SavePreparseData(Parser* parser);
634 
635   // Create a non-local variable with a given name.
636   // These variables are looked up dynamically at runtime.
637   Variable* NonLocal(const AstRawString* name, VariableMode mode);
638 
639   enum ScopeLookupMode {
640     kParsedScope,
641     kDeserializedScope,
642   };
643 
644   // Variable resolution.
645   // Lookup a variable reference given by name starting with this scope, and
646   // stopping when reaching the outer_scope_end scope. If the code is executed
647   // because of a call to 'eval', the context parameter should be set to the
648   // calling context of 'eval'.
649   template <ScopeLookupMode mode>
650   static Variable* Lookup(VariableProxy* proxy, Scope* scope,
651                           Scope* outer_scope_end, Scope* cache_scope = nullptr,
652                           bool force_context_allocation = false);
653   static Variable* LookupWith(VariableProxy* proxy, Scope* scope,
654                               Scope* outer_scope_end, Scope* cache_scope,
655                               bool force_context_allocation);
656   static Variable* LookupSloppyEval(VariableProxy* proxy, Scope* scope,
657                                     Scope* outer_scope_end, Scope* cache_scope,
658                                     bool force_context_allocation);
659   static void ResolvePreparsedVariable(VariableProxy* proxy, Scope* scope,
660                                        Scope* end);
661   void ResolveTo(VariableProxy* proxy, Variable* var);
662   void ResolveVariable(VariableProxy* proxy);
663   V8_WARN_UNUSED_RESULT bool ResolveVariablesRecursively(Scope* end);
664 
665   // Finds free variables of this scope. This mutates the unresolved variables
666   // list along the way, so full resolution cannot be done afterwards.
667   void AnalyzePartially(DeclarationScope* max_outer_scope,
668                         AstNodeFactory* ast_node_factory,
669                         UnresolvedList* new_unresolved_list,
670                         bool maybe_in_arrowhead);
671   void CollectNonLocals(DeclarationScope* max_outer_scope, Isolate* isolate,
672                         Handle<StringSet>* non_locals);
673 
674   // Predicates.
675   bool MustAllocate(Variable* var);
676   bool MustAllocateInContext(Variable* var);
677 
678   // Variable allocation.
679   void AllocateStackSlot(Variable* var);
680   V8_INLINE void AllocateHeapSlot(Variable* var);
681   void AllocateNonParameterLocal(Variable* var);
682   void AllocateDeclaredGlobal(Variable* var);
683   V8_INLINE void AllocateNonParameterLocalsAndDeclaredGlobals();
684   void AllocateVariablesRecursively();
685 
686   template <typename LocalIsolate>
687   void AllocateScopeInfosRecursively(LocalIsolate* isolate,
688                                      MaybeHandle<ScopeInfo> outer_scope);
689 
690   void AllocateDebuggerScopeInfos(Isolate* isolate,
691                                   MaybeHandle<ScopeInfo> outer_scope);
692 
693   // Construct a scope based on the scope info.
694   Scope(Zone* zone, ScopeType type, Handle<ScopeInfo> scope_info);
695 
696   // Construct a catch scope with a binding for the name.
697   Scope(Zone* zone, const AstRawString* catch_variable_name,
698         MaybeAssignedFlag maybe_assigned, Handle<ScopeInfo> scope_info);
699 
700   void AddInnerScope(Scope* inner_scope) {
701     inner_scope->sibling_ = inner_scope_;
702     inner_scope_ = inner_scope;
703     inner_scope->outer_scope_ = this;
704   }
705 
706   void SetDefaults();
707 
708   friend class DeclarationScope;
709   friend class ClassScope;
710   friend class ScopeTestHelper;
711   friend Zone;
712 
713   // Scope tree.
714   Scope* outer_scope_;  // the immediately enclosing outer scope, or nullptr
715   Scope* inner_scope_;  // an inner scope of this scope
716   Scope* sibling_;  // a sibling inner scope of the outer scope of this scope.
717 
718   // The variables declared in this scope:
719   //
720   // All user-declared variables (incl. parameters).  For script scopes
721   // variables may be implicitly 'declared' by being used (possibly in
722   // an inner scope) with no intervening with statements or eval calls.
723   VariableMap variables_;
724   // In case of non-scopeinfo-backed scopes, this contains the variables of the
725   // map above in order of addition.
726   base::ThreadedList<Variable> locals_;
727   // Unresolved variables referred to from this scope. The proxies themselves
728   // form a linked list of all unresolved proxies.
729   UnresolvedList unresolved_list_;
730   // Declarations.
731   base::ThreadedList<Declaration> decls_;
732 
733   // Serialized scope info support.
734   Handle<ScopeInfo> scope_info_;
735 // Debugging support.
736 #ifdef DEBUG
737   const AstRawString* scope_name_;
738 
739   // True if it doesn't need scope resolution (e.g., if the scope was
740   // constructed based on a serialized scope info or a catch context).
741   bool already_resolved_;
742   // True if this scope may contain objects from a temp zone that needs to be
743   // fixed up.
744   bool needs_migration_;
745 #endif
746 
747   // Source positions.
748   int start_position_;
749   int end_position_;
750 
751   // Computed via AllocateVariables.
752   int num_stack_slots_;
753   int num_heap_slots_;
754 
755   // The scope type.
756   const ScopeType scope_type_;
757 
758   // Scope-specific information computed during parsing.
759   //
760   // The language mode of this scope.
761   STATIC_ASSERT(LanguageModeSize == 2);
762   bool is_strict_ : 1;
763   // This scope contains an 'eval' call.
764   bool calls_eval_ : 1;
765   // The context associated with this scope can be extended by a sloppy eval
766   // called inside of it.
767   bool sloppy_eval_can_extend_vars_ : 1;
768   // This scope's declarations might not be executed in order (e.g., switch).
769   bool scope_nonlinear_ : 1;
770   bool is_hidden_ : 1;
771   // Temporary workaround that allows masking of 'this' in debug-evaluate
772   // scopes.
773   bool is_debug_evaluate_scope_ : 1;
774 
775   // True if one of the inner scopes or the scope itself calls eval.
776   bool inner_scope_calls_eval_ : 1;
777   bool force_context_allocation_for_parameters_ : 1;
778 
779   // True if it holds 'var' declarations.
780   bool is_declaration_scope_ : 1;
781 
782   // True if the outer scope is a class scope and should be skipped when
783   // resolving private names, i.e. if the scope is in a class heritage
784   // expression.
785   bool private_name_lookup_skips_outer_class_ : 1;
786 
787   bool must_use_preparsed_scope_data_ : 1;
788 
789   // True if this is a script scope that originated from
790   // DebugEvaluate::GlobalREPL().
791   bool is_repl_mode_scope_ : 1;
792 
793   // True if this is a deserialized scope which caches its lookups on another
794   // Scope's variable map. This will be true for every scope above the first
795   // non-eval declaration scope above the compilation entry point, e.g. for
796   //
797   //     function f() {
798   //       let g; // prevent sloppy block function hoisting.
799   //       with({}) {
800   //         function g() {
801   //           try { throw 0; }
802   //           catch { eval("f"); }
803   //         }
804   //         g();
805   //       }
806   //     }
807   //
808   // the compilation of the eval will have the "with" scope as the first scope
809   // with this flag enabled.
810   bool deserialized_scope_uses_external_cache_ : 1;
811 };
812 
813 class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
814  public:
815   DeclarationScope(Zone* zone, Scope* outer_scope, ScopeType scope_type,
816                    FunctionKind function_kind = kNormalFunction);
817   DeclarationScope(Zone* zone, ScopeType scope_type,
818                    Handle<ScopeInfo> scope_info);
819   // Creates a script scope.
820   DeclarationScope(Zone* zone, AstValueFactory* ast_value_factory,
821                    REPLMode repl_mode = REPLMode::kNo);
822 
823   FunctionKind function_kind() const { return function_kind_; }
824 
825   bool is_arrow_scope() const {
826     return is_function_scope() && IsArrowFunction(function_kind_);
827   }
828 
829   // Inform the scope that the corresponding code uses "super".
830   void RecordSuperPropertyUsage() {
831     DCHECK(IsConciseMethod(function_kind()) ||
832            IsAccessorFunction(function_kind()) ||
833            IsClassConstructor(function_kind()));
834     scope_uses_super_property_ = true;
835   }
836 
837   // Does this scope access "super" property (super.foo).
838   bool NeedsHomeObject() const {
839     return scope_uses_super_property_ ||
840            (inner_scope_calls_eval_ && (IsConciseMethod(function_kind()) ||
841                                         IsAccessorFunction(function_kind()) ||
842                                         IsClassConstructor(function_kind())));
843   }
844 
845   // Inform the scope and outer scopes that the corresponding code contains an
846   // eval call.
847   void RecordDeclarationScopeEvalCall() {
848     calls_eval_ = true;
849 
850     // If this isn't a sloppy eval, we don't care about it.
851     if (language_mode() != LanguageMode::kSloppy) return;
852 
853     // Sloppy eval in script scopes can only introduce global variables anyway,
854     // so we don't care that it calls sloppy eval.
855     if (is_script_scope()) return;
856 
857     // Sloppy eval in a eval scope can only introduce variables into the outer
858     // (non-eval) declaration scope, not into this eval scope.
859     if (is_eval_scope()) {
860 #ifdef DEBUG
861       // One of three things must be true:
862       //   1. The outer non-eval declaration scope should already be marked as
863       //      being extendable by sloppy eval, by the current sloppy eval rather
864       //      than the inner one,
865       //   2. The outer non-eval declaration scope is a script scope and thus
866       //      isn't extendable anyway, or
867       //   3. This is a debug evaluate and all bets are off.
868       DeclarationScope* outer_decl_scope = outer_scope()->GetDeclarationScope();
869       while (outer_decl_scope->is_eval_scope()) {
870         outer_decl_scope = outer_decl_scope->GetDeclarationScope();
871       }
872       if (outer_decl_scope->is_debug_evaluate_scope()) {
873         // Don't check anything.
874         // TODO(9662): Figure out where variables declared by an eval inside a
875         // debug-evaluate actually go.
876       } else if (!outer_decl_scope->is_script_scope()) {
877         DCHECK(outer_decl_scope->sloppy_eval_can_extend_vars_);
878       }
879 #endif
880 
881       return;
882     }
883 
884     sloppy_eval_can_extend_vars_ = true;
885     num_heap_slots_ = Context::MIN_CONTEXT_EXTENDED_SLOTS;
886   }
887 
888   bool sloppy_eval_can_extend_vars() const {
889     return sloppy_eval_can_extend_vars_;
890   }
891 
892   bool was_lazily_parsed() const { return was_lazily_parsed_; }
893 
894   Variable* LookupInModule(const AstRawString* name) {
895     DCHECK(is_module_scope());
896     Variable* var = variables_.Lookup(name);
897     DCHECK_NOT_NULL(var);
898     return var;
899   }
900 
901   void DeserializeReceiver(AstValueFactory* ast_value_factory);
902 
903 #ifdef DEBUG
904   void set_is_being_lazily_parsed(bool is_being_lazily_parsed) {
905     is_being_lazily_parsed_ = is_being_lazily_parsed;
906   }
907   bool is_being_lazily_parsed() const { return is_being_lazily_parsed_; }
908 #endif
909 
910   void set_zone(Zone* zone) {
911 #ifdef DEBUG
912     needs_migration_ = true;
913 #endif
914     // Migrate variables_' backing store to new zone.
915     variables_ = VariableMap(variables_, zone);
916   }
917 
918   // ---------------------------------------------------------------------------
919   // Illegal redeclaration support.
920 
921   // Check if the scope has conflicting var
922   // declarations, i.e. a var declaration that has been hoisted from a nested
923   // scope over a let binding of the same name.
924   Declaration* CheckConflictingVarDeclarations(
925       bool* allowed_catch_binding_var_redeclaration);
926 
927   void set_has_checked_syntax(bool has_checked_syntax) {
928     has_checked_syntax_ = has_checked_syntax;
929   }
930   bool has_checked_syntax() const { return has_checked_syntax_; }
931 
932   bool ShouldEagerCompile() const {
933     return force_eager_compilation_ || should_eager_compile_;
934   }
935 
936   void set_should_eager_compile();
937 
938   void SetScriptScopeInfo(Handle<ScopeInfo> scope_info) {
939     DCHECK(is_script_scope());
940     DCHECK(scope_info_.is_null());
941     scope_info_ = scope_info;
942   }
943 
944   bool is_asm_module() const { return is_asm_module_; }
945   void set_is_asm_module();
946 
947   bool should_ban_arguments() const {
948     return IsClassMembersInitializerFunction(function_kind());
949   }
950 
951   void set_is_async_module() {
952     DCHECK(IsModule(function_kind_));
953     function_kind_ = kAsyncModule;
954   }
955 
956   void DeclareThis(AstValueFactory* ast_value_factory);
957   void DeclareArguments(AstValueFactory* ast_value_factory);
958   void DeclareDefaultFunctionVariables(AstValueFactory* ast_value_factory);
959 
960   // Declare the function variable for a function literal. This variable
961   // is in an intermediate scope between this function scope and the the
962   // outer scope. Only possible for function scopes; at most one variable.
963   //
964   // This function needs to be called after all other variables have been
965   // declared in the scope. It will add a variable for {name} to {variables_};
966   // either the function variable itself, or a non-local in case the function
967   // calls sloppy eval.
968   Variable* DeclareFunctionVar(const AstRawString* name,
969                                Scope* cache = nullptr);
970 
971   // Declare some special internal variables which must be accessible to
972   // Ignition without ScopeInfo.
973   Variable* DeclareGeneratorObjectVar(const AstRawString* name);
974 
975   // Declare a parameter in this scope.  When there are duplicated
976   // parameters the rightmost one 'wins'.  However, the implementation
977   // expects all parameters to be declared and from left to right.
978   Variable* DeclareParameter(const AstRawString* name, VariableMode mode,
979                              bool is_optional, bool is_rest,
980                              AstValueFactory* ast_value_factory, int position);
981 
982   // Makes sure that num_parameters_ and has_rest is correct for the preparser.
983   void RecordParameter(bool is_rest);
984 
985   // Declare an implicit global variable in this scope which must be a
986   // script scope.  The variable was introduced (possibly from an inner
987   // scope) by a reference to an unresolved variable with no intervening
988   // with statements or eval calls.
989   Variable* DeclareDynamicGlobal(const AstRawString* name,
990                                  VariableKind variable_kind, Scope* cache);
991 
992   // The variable corresponding to the 'this' value.
993   Variable* receiver() {
994     DCHECK(has_this_declaration() || is_script_scope());
995     DCHECK_NOT_NULL(receiver_);
996     return receiver_;
997   }
998 
999   bool has_this_declaration() const { return has_this_declaration_; }
1000 
1001   // The variable corresponding to the 'new.target' value.
1002   Variable* new_target_var() { return new_target_; }
1003 
1004   // The variable holding the function literal for named function
1005   // literals, or nullptr.  Only valid for function scopes.
1006   Variable* function_var() const { return function_; }
1007 
1008   // The variable holding the JSGeneratorObject for generator, async
1009   // and async generator functions, and modules. Only valid for
1010   // function, module and REPL mode script scopes.
1011   Variable* generator_object_var() const {
1012     DCHECK(is_function_scope() || is_module_scope() || is_repl_mode_scope());
1013     return GetRareVariable(RareVariable::kGeneratorObject);
1014   }
1015 
1016   // Parameters. The left-most parameter has index 0.
1017   // Only valid for function and module scopes.
1018   Variable* parameter(int index) const {
1019     DCHECK(is_function_scope() || is_module_scope());
1020     DCHECK(!is_being_lazily_parsed_);
1021     return params_[index];
1022   }
1023 
1024   // Returns the number of formal parameters, excluding a possible rest
1025   // parameter.  Examples:
1026   //   function foo(a, b) {}         ==> 2
1027   //   function foo(a, b, ...c) {}   ==> 2
1028   //   function foo(a, b, c = 1) {}  ==> 3
1029   int num_parameters() const { return num_parameters_; }
1030 
1031   // The function's rest parameter (nullptr if there is none).
1032   Variable* rest_parameter() const {
1033     return has_rest_ ? params_[params_.length() - 1] : nullptr;
1034   }
1035 
1036   bool has_simple_parameters() const { return has_simple_parameters_; }
1037 
1038   // TODO(caitp): manage this state in a better way. PreParser must be able to
1039   // communicate that the scope is non-simple, without allocating any parameters
1040   // as the Parser does. This is necessary to ensure that TC39's proposed early
1041   // error can be reported consistently regardless of whether lazily parsed or
1042   // not.
1043   void SetHasNonSimpleParameters() {
1044     DCHECK(is_function_scope());
1045     has_simple_parameters_ = false;
1046   }
1047 
1048   void MakeParametersNonSimple() {
1049     SetHasNonSimpleParameters();
1050     for (ZoneHashMap::Entry* p = variables_.Start(); p != nullptr;
1051          p = variables_.Next(p)) {
1052       Variable* var = reinterpret_cast<Variable*>(p->value);
1053       if (var->is_parameter()) var->MakeParameterNonSimple();
1054     }
1055   }
1056 
1057   // Returns whether the arguments object aliases formal parameters.
1058   CreateArgumentsType GetArgumentsType() const {
1059     DCHECK(is_function_scope());
1060     DCHECK(!is_arrow_scope());
1061     DCHECK_NOT_NULL(arguments_);
1062     return is_sloppy(language_mode()) && has_simple_parameters()
1063                ? CreateArgumentsType::kMappedArguments
1064                : CreateArgumentsType::kUnmappedArguments;
1065   }
1066 
1067   // The local variable 'arguments' if we need to allocate it; nullptr
1068   // otherwise.
1069   Variable* arguments() const {
1070     DCHECK_IMPLIES(is_arrow_scope(), arguments_ == nullptr);
1071     return arguments_;
1072   }
1073 
1074   Variable* this_function_var() const {
1075     Variable* this_function = GetRareVariable(RareVariable::kThisFunction);
1076 
1077     // This is only used in derived constructors atm.
1078     DCHECK(this_function == nullptr ||
1079            (is_function_scope() && (IsClassConstructor(function_kind()) ||
1080                                     IsConciseMethod(function_kind()) ||
1081                                     IsAccessorFunction(function_kind()))));
1082     return this_function;
1083   }
1084 
1085   // Adds a local variable in this scope's locals list. This is for adjusting
1086   // the scope of temporaries and do-expression vars when desugaring parameter
1087   // initializers.
1088   void AddLocal(Variable* var);
1089 
1090   void DeclareSloppyBlockFunction(
1091       SloppyBlockFunctionStatement* sloppy_block_function);
1092 
1093   // Go through sloppy_block_functions_ and hoist those (into this scope)
1094   // which should be hoisted.
1095   void HoistSloppyBlockFunctions(AstNodeFactory* factory);
1096 
1097   // Compute top scope and allocate variables. For lazy compilation the top
1098   // scope only contains the single lazily compiled function, so this
1099   // doesn't re-allocate variables repeatedly.
1100   //
1101   // Returns false if private names can not be resolved and
1102   // ParseInfo's pending_error_handler will be populated with an
1103   // error. Otherwise, returns true.
1104   V8_WARN_UNUSED_RESULT
1105   static bool Analyze(ParseInfo* info);
1106 
1107   // To be called during parsing. Do just enough scope analysis that we can
1108   // discard the Scope contents for lazily compiled functions. In particular,
1109   // this records variables which cannot be resolved inside the Scope (we don't
1110   // yet know what they will resolve to since the outer Scopes are incomplete)
1111   // and recreates them with the correct Zone with ast_node_factory.
1112   void AnalyzePartially(Parser* parser, AstNodeFactory* ast_node_factory,
1113                         bool maybe_in_arrowhead);
1114 
1115   // Allocate ScopeInfos for top scope and any inner scopes that need them.
1116   // Does nothing if ScopeInfo is already allocated.
1117   template <typename LocalIsolate>
1118   V8_EXPORT_PRIVATE static void AllocateScopeInfos(ParseInfo* info,
1119                                                    LocalIsolate* isolate);
1120 
1121   Handle<StringSet> CollectNonLocals(Isolate* isolate,
1122                                      Handle<StringSet> non_locals);
1123 
1124   // Determine if we can use lazy compilation for this scope.
1125   bool AllowsLazyCompilation() const;
1126 
1127   // Make sure this closure and all outer closures are eagerly compiled.
1128   void ForceEagerCompilation() {
1129     DCHECK_EQ(this, GetClosureScope());
1130     DeclarationScope* s;
1131     for (s = this; !s->is_script_scope();
1132          s = s->outer_scope()->GetClosureScope()) {
1133       s->force_eager_compilation_ = true;
1134     }
1135     s->force_eager_compilation_ = true;
1136   }
1137 
1138 #ifdef DEBUG
1139   void PrintParameters();
1140 #endif
1141 
1142   V8_INLINE void AllocateLocals();
1143   V8_INLINE void AllocateParameterLocals();
1144   V8_INLINE void AllocateReceiver();
1145 
1146   void ResetAfterPreparsing(AstValueFactory* ast_value_factory, bool aborted);
1147 
1148   bool is_skipped_function() const { return is_skipped_function_; }
1149   void set_is_skipped_function(bool is_skipped_function) {
1150     is_skipped_function_ = is_skipped_function;
1151   }
1152 
1153   bool has_inferred_function_name() const {
1154     return has_inferred_function_name_;
1155   }
1156   void set_has_inferred_function_name(bool value) {
1157     DCHECK(is_function_scope());
1158     has_inferred_function_name_ = value;
1159   }
1160 
1161   // Save data describing the context allocation of the variables in this scope
1162   // and its subscopes (except scopes at the laziness boundary). The data is
1163   // saved in produced_preparse_data_.
1164   void SavePreparseDataForDeclarationScope(Parser* parser);
1165 
1166   void set_preparse_data_builder(PreparseDataBuilder* preparse_data_builder) {
1167     preparse_data_builder_ = preparse_data_builder;
1168   }
1169 
1170   PreparseDataBuilder* preparse_data_builder() const {
1171     return preparse_data_builder_;
1172   }
1173 
1174   void set_has_this_reference() { has_this_reference_ = true; }
1175   bool has_this_reference() const { return has_this_reference_; }
1176   void UsesThis() {
1177     set_has_this_reference();
1178     GetReceiverScope()->receiver()->ForceContextAllocation();
1179   }
1180 
1181   bool needs_private_name_context_chain_recalc() const {
1182     return needs_private_name_context_chain_recalc_;
1183   }
1184   void RecordNeedsPrivateNameContextChainRecalc();
1185 
1186   // Re-writes the {VariableLocation} of top-level 'let' bindings from CONTEXT
1187   // to REPL_GLOBAL. Should only be called on REPL scripts.
1188   void RewriteReplGlobalVariables();
1189 
1190  private:
1191   V8_INLINE void AllocateParameter(Variable* var, int index);
1192 
1193   // Resolve and fill in the allocation information for all variables
1194   // in this scopes. Must be called *after* all scopes have been
1195   // processed (parsed) to ensure that unresolved variables can be
1196   // resolved properly.
1197   //
1198   // In the case of code compiled and run using 'eval', the context
1199   // parameter is the context in which eval was called.  In all other
1200   // cases the context parameter is an empty handle.
1201   //
1202   // Returns false if private names can not be resolved.
1203   bool AllocateVariables(ParseInfo* info);
1204 
1205   void SetDefaults();
1206 
1207   // Recalculate the private name context chain from the existing skip bit in
1208   // preparation for AllocateScopeInfos. Because the private name scope is
1209   // implemented with a skip bit for scopes in heritage position, that bit may
1210   // need to be recomputed due scopes that do not need contexts.
1211   void RecalcPrivateNameContextChain();
1212 
1213   bool has_simple_parameters_ : 1;
1214   // This scope contains an "use asm" annotation.
1215   bool is_asm_module_ : 1;
1216   bool force_eager_compilation_ : 1;
1217   // This function scope has a rest parameter.
1218   bool has_rest_ : 1;
1219   // This scope has a parameter called "arguments".
1220   bool has_arguments_parameter_ : 1;
1221   // This scope uses "super" property ('super.foo').
1222   bool scope_uses_super_property_ : 1;
1223   bool should_eager_compile_ : 1;
1224   // Set to true after we have finished lazy parsing the scope.
1225   bool was_lazily_parsed_ : 1;
1226 #if DEBUG
1227   bool is_being_lazily_parsed_ : 1;
1228 #endif
1229   bool is_skipped_function_ : 1;
1230   bool has_inferred_function_name_ : 1;
1231   bool has_checked_syntax_ : 1;
1232   bool has_this_reference_ : 1;
1233   bool has_this_declaration_ : 1;
1234   bool needs_private_name_context_chain_recalc_ : 1;
1235 
1236   // If the scope is a function scope, this is the function kind.
1237   FunctionKind function_kind_;
1238 
1239   int num_parameters_ = 0;
1240 
1241   // Parameter list in source order.
1242   ZonePtrList<Variable> params_;
1243   // Map of function names to lists of functions defined in sloppy blocks
1244   base::ThreadedList<SloppyBlockFunctionStatement> sloppy_block_functions_;
1245   // Convenience variable.
1246   Variable* receiver_;
1247   // Function variable, if any; function scopes only.
1248   Variable* function_;
1249   // new.target variable, function scopes only.
1250   Variable* new_target_;
1251   // Convenience variable; function scopes only.
1252   Variable* arguments_;
1253 
1254   // For producing the scope allocation data during preparsing.
1255   PreparseDataBuilder* preparse_data_builder_;
1256 
1257   struct RareData : public ZoneObject {
1258     // Convenience variable; Subclass constructor only
1259     Variable* this_function = nullptr;
1260 
1261     // Generator object, if any; generator function scopes and module scopes
1262     // only.
1263     Variable* generator_object = nullptr;
1264   };
1265 
1266   enum class RareVariable {
1267     kThisFunction = offsetof(RareData, this_function),
1268     kGeneratorObject = offsetof(RareData, generator_object),
1269   };
1270 
1271   V8_INLINE RareData* EnsureRareData() {
1272     if (rare_data_ == nullptr) {
1273       rare_data_ = zone()->New<RareData>();
1274     }
1275     return rare_data_;
1276   }
1277 
1278   V8_INLINE Variable* GetRareVariable(RareVariable id) const {
1279     if (rare_data_ == nullptr) return nullptr;
1280     return *reinterpret_cast<Variable**>(
1281         reinterpret_cast<uint8_t*>(rare_data_) + static_cast<ptrdiff_t>(id));
1282   }
1283 
1284   // Set `var` to null if it's non-null and Predicate (Variable*) -> bool
1285   // returns true.
1286   template <typename Predicate>
1287   V8_INLINE void NullifyRareVariableIf(RareVariable id, Predicate predicate) {
1288     if (V8_LIKELY(rare_data_ == nullptr)) return;
1289     Variable** var = reinterpret_cast<Variable**>(
1290         reinterpret_cast<uint8_t*>(rare_data_) + static_cast<ptrdiff_t>(id));
1291     if (*var && predicate(*var)) *var = nullptr;
1292   }
1293 
1294   RareData* rare_data_ = nullptr;
1295 };
1296 
1297 void Scope::RecordEvalCall() {
1298   calls_eval_ = true;
1299   GetDeclarationScope()->RecordDeclarationScopeEvalCall();
1300   RecordInnerScopeEvalCall();
1301 }
1302 
1303 Scope::Snapshot::Snapshot(Scope* scope)
1304     : outer_scope_and_calls_eval_(scope, scope->calls_eval_),
1305       top_inner_scope_(scope->inner_scope_),
1306       top_unresolved_(scope->unresolved_list_.end()),
1307       top_local_(scope->GetClosureScope()->locals_.end()) {
1308   // Reset in order to record eval calls during this Snapshot's lifetime.
1309   outer_scope_and_calls_eval_.GetPointer()->calls_eval_ = false;
1310   outer_scope_and_calls_eval_.GetPointer()->sloppy_eval_can_extend_vars_ =
1311       false;
1312 }
1313 
1314 class ModuleScope final : public DeclarationScope {
1315  public:
1316   ModuleScope(DeclarationScope* script_scope, AstValueFactory* avfactory);
1317 
1318   // Deserialization. Does not restore the module descriptor.
1319   ModuleScope(Isolate* isolate, Handle<ScopeInfo> scope_info,
1320               AstValueFactory* avfactory);
1321 
1322   // Returns nullptr in a deserialized scope.
1323   SourceTextModuleDescriptor* module() const { return module_descriptor_; }
1324 
1325   // Set MODULE as VariableLocation for all variables that will live in a
1326   // module's export table.
1327   void AllocateModuleVariables();
1328 
1329  private:
1330   SourceTextModuleDescriptor* const module_descriptor_;
1331 };
1332 
1333 class V8_EXPORT_PRIVATE ClassScope : public Scope {
1334  public:
1335   ClassScope(Zone* zone, Scope* outer_scope, bool is_anonymous);
1336   // Deserialization.
1337   ClassScope(Isolate* isolate, Zone* zone, AstValueFactory* ast_value_factory,
1338              Handle<ScopeInfo> scope_info);
1339 
1340   struct HeritageParsingScope {
1341     explicit HeritageParsingScope(ClassScope* class_scope)
1342         : class_scope_(class_scope) {
1343       class_scope_->SetIsParsingHeritage(true);
1344     }
1345     ~HeritageParsingScope() { class_scope_->SetIsParsingHeritage(false); }
1346 
1347    private:
1348     ClassScope* class_scope_;
1349   };
1350 
1351   // Declare a private name in the private name map and add it to the
1352   // local variables of this scope.
1353   Variable* DeclarePrivateName(const AstRawString* name, VariableMode mode,
1354                                IsStaticFlag is_static_flag, bool* was_added);
1355 
1356   // Try resolving all unresolved private names found in the current scope.
1357   // Called from DeclarationScope::AllocateVariables() when reparsing a
1358   // method to generate code or when eval() is called to access private names.
1359   // If there are any private names that cannot be resolved, returns false.
1360   V8_WARN_UNUSED_RESULT bool ResolvePrivateNames(ParseInfo* info);
1361 
1362   // Called after the entire class literal is parsed.
1363   // - If we are certain a private name cannot be resolve, return that
1364   //   variable proxy.
1365   // - If we find the private name in the scope chain, return nullptr.
1366   //   If the name is found in the current class scope, resolve it
1367   //   immediately.
1368   // - If we are not sure if the private name can be resolved or not yet,
1369   //   return nullptr.
1370   VariableProxy* ResolvePrivateNamesPartially();
1371 
1372   // Get the current tail of unresolved private names to be used to
1373   // reset the tail.
1374   UnresolvedList::Iterator GetUnresolvedPrivateNameTail();
1375 
1376   // Reset the tail of unresolved private names, discard everything
1377   // between the tail passed into this method and the current tail.
1378   void ResetUnresolvedPrivateNameTail(UnresolvedList::Iterator tail);
1379 
1380   // Migrate private names added between the tail passed into this method
1381   // and the current tail.
1382   void MigrateUnresolvedPrivateNameTail(AstNodeFactory* ast_node_factory,
1383                                         UnresolvedList::Iterator tail);
1384   Variable* DeclareBrandVariable(AstValueFactory* ast_value_factory,
1385                                  IsStaticFlag is_static_flag,
1386                                  int class_token_pos);
1387 
1388   Variable* DeclareClassVariable(AstValueFactory* ast_value_factory,
1389                                  const AstRawString* name, int class_token_pos);
1390 
1391   Variable* brand() {
1392     return GetRareData() == nullptr ? nullptr : GetRareData()->brand;
1393   }
1394 
1395   Variable* class_variable() { return class_variable_; }
1396 
1397   V8_INLINE bool IsParsingHeritage() {
1398     return rare_data_and_is_parsing_heritage_.GetPayload();
1399   }
1400 
1401   // Only maintained when the scope is parsed, not when the scope is
1402   // deserialized.
1403   bool has_static_private_methods() const {
1404     return has_static_private_methods_;
1405   }
1406 
1407   // Returns whether the index of class variable of this class scope should be
1408   // recorded in the ScopeInfo.
1409   // If any inner scope accesses static private names directly, the class
1410   // variable will be forced to be context-allocated.
1411   // The inner scope may also calls eval which may results in access to
1412   // static private names.
1413   // Only maintained when the scope is parsed.
1414   bool should_save_class_variable_index() const {
1415     return should_save_class_variable_index_ ||
1416            has_explicit_static_private_methods_access_ ||
1417            (has_static_private_methods_ && inner_scope_calls_eval_);
1418   }
1419 
1420   // Only maintained when the scope is parsed.
1421   bool is_anonymous_class() const { return is_anonymous_class_; }
1422 
1423   // Overriden during reparsing
1424   void set_should_save_class_variable_index() {
1425     should_save_class_variable_index_ = true;
1426   }
1427 
1428  private:
1429   friend class Scope;
1430   friend class PrivateNameScopeIterator;
1431 
1432   // Find the private name declared in the private name map first,
1433   // if it cannot be found there, try scope info if there is any.
1434   // Returns nullptr if it cannot be found.
1435   Variable* LookupPrivateName(VariableProxy* proxy);
1436   // Lookup a private name from the local private name map of the current
1437   // scope.
1438   Variable* LookupLocalPrivateName(const AstRawString* name);
1439   // Lookup a private name from the scope info of the current scope.
1440   Variable* LookupPrivateNameInScopeInfo(const AstRawString* name);
1441 
1442   struct RareData : public ZoneObject {
1443     explicit RareData(Zone* zone) : private_name_map(zone) {}
1444     UnresolvedList unresolved_private_names;
1445     VariableMap private_name_map;
1446     Variable* brand = nullptr;
1447   };
1448 
1449   V8_INLINE RareData* GetRareData() {
1450     return rare_data_and_is_parsing_heritage_.GetPointer();
1451   }
1452   V8_INLINE RareData* EnsureRareData() {
1453     if (GetRareData() == nullptr) {
1454       rare_data_and_is_parsing_heritage_.SetPointer(
1455           zone()->New<RareData>(zone()));
1456     }
1457     return GetRareData();
1458   }
1459   V8_INLINE void SetIsParsingHeritage(bool v) {
1460     rare_data_and_is_parsing_heritage_.SetPayload(v);
1461   }
1462 
1463   PointerWithPayload<RareData, bool, 1> rare_data_and_is_parsing_heritage_;
1464   Variable* class_variable_ = nullptr;
1465   // These are only maintained when the scope is parsed, not when the
1466   // scope is deserialized.
1467   bool has_static_private_methods_ = false;
1468   bool has_explicit_static_private_methods_access_ = false;
1469   bool is_anonymous_class_ = false;
1470   // This is only maintained during reparsing, restored from the
1471   // preparsed data.
1472   bool should_save_class_variable_index_ = false;
1473 };
1474 
1475 // Iterate over the private name scope chain. The iteration proceeds from the
1476 // innermost private name scope outwards.
1477 class PrivateNameScopeIterator {
1478  public:
1479   explicit PrivateNameScopeIterator(Scope* start);
1480 
1481   bool Done() const { return current_scope_ == nullptr; }
1482   void Next();
1483 
1484   // Add an unresolved private name to the current scope.
1485   void AddUnresolvedPrivateName(VariableProxy* proxy);
1486 
1487   ClassScope* GetScope() const {
1488     DCHECK(!Done());
1489     return current_scope_->AsClassScope();
1490   }
1491 
1492  private:
1493   bool skipped_any_scopes_ = false;
1494   Scope* start_scope_;
1495   Scope* current_scope_;
1496 };
1497 
1498 }  // namespace internal
1499 }  // namespace v8
1500 
1501 #endif  // V8_AST_SCOPES_H_
1502