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