xref: /third_party/node/deps/v8/src/ast/scopes.h (revision 1cb0ef41)
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
22namespace v8 {
23
24namespace internal {
25class Scope;
26}  // namespace internal
27
28namespace base {
29template <>
30struct PointerWithPayloadTraits<v8::internal::Scope> {
31  static constexpr int kAvailableBits = 1;
32};
33}  // namespace base
34
35namespace internal {
36
37class AstNodeFactory;
38class AstValueFactory;
39class AstRawString;
40class Declaration;
41class ParseInfo;
42class Parser;
43class PreparseDataBuilder;
44class SloppyBlockFunctionStatement;
45class Statement;
46class StringSet;
47class VariableProxy;
48
49using UnresolvedList =
50    base::ThreadedList<VariableProxy, VariableProxy::UnresolvedNext>;
51
52// A hash map to support fast variable declaration and lookup.
53class 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.
92class 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
856class 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
1349void 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
1365Scope::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
1380class 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
1398class 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.
1559class 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