LCOV - code coverage report
Current view: top level - src/ast - scopes.h (source / functions) Hit Total Coverage
Test: app.info Lines: 110 110 100.0 %
Date: 2019-03-21 Functions: 6 6 100.0 %

          Line data    Source code
       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 "src/ast/ast.h"
       9             : #include "src/base/compiler-specific.h"
      10             : #include "src/base/hashmap.h"
      11             : #include "src/base/threaded-list.h"
      12             : #include "src/function-kind.h"
      13             : #include "src/globals.h"
      14             : #include "src/objects.h"
      15             : #include "src/pointer-with-payload.h"
      16             : #include "src/zone/zone.h"
      17             : 
      18             : namespace v8 {
      19             : namespace internal {
      20             : 
      21             : class AstNodeFactory;
      22             : class AstValueFactory;
      23             : class AstRawString;
      24             : class Declaration;
      25             : class ParseInfo;
      26             : class Parser;
      27             : class PreparseDataBuilder;
      28             : class SloppyBlockFunctionStatement;
      29             : class Statement;
      30             : class StringSet;
      31             : class VariableProxy;
      32             : 
      33             : // A hash map to support fast variable declaration and lookup.
      34           1 : class VariableMap: public ZoneHashMap {
      35             :  public:
      36             :   explicit VariableMap(Zone* zone);
      37             : 
      38             :   Variable* Declare(Zone* zone, Scope* scope, const AstRawString* name,
      39             :                     VariableMode mode, VariableKind kind,
      40             :                     InitializationFlag initialization_flag,
      41             :                     MaybeAssignedFlag maybe_assigned_flag, bool* was_added);
      42             : 
      43             :   Variable* Lookup(const AstRawString* name);
      44             :   void Remove(Variable* var);
      45             :   void Add(Zone* zone, Variable* var);
      46             : };
      47             : 
      48             : class Scope;
      49             : 
      50             : template <>
      51             : struct PointerWithPayloadTraits<Scope> {
      52             :   static constexpr int value = 1;
      53             : };
      54             : 
      55             : // Global invariants after AST construction: Each reference (i.e. identifier)
      56             : // to a JavaScript variable (including global properties) is represented by a
      57             : // VariableProxy node. Immediately after AST construction and before variable
      58             : // allocation, most VariableProxy nodes are "unresolved", i.e. not bound to a
      59             : // corresponding variable (though some are bound during parse time). Variable
      60             : // allocation binds each unresolved VariableProxy to one Variable and assigns
      61             : // a location. Note that many VariableProxy nodes may refer to the same Java-
      62             : // Script variable.
      63             : 
      64             : // JS environments are represented in the parser using Scope, DeclarationScope
      65             : // and ModuleScope. DeclarationScope is used for any scope that hosts 'var'
      66             : // declarations. This includes script, module, eval, varblock, and function
      67             : // scope. ModuleScope further specializes DeclarationScope.
      68           1 : class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
      69             :  public:
      70             :   // ---------------------------------------------------------------------------
      71             :   // Construction
      72             : 
      73             :   Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type);
      74             : 
      75             : #ifdef DEBUG
      76             :   // The scope name is only used for printing/debugging.
      77             :   void SetScopeName(const AstRawString* scope_name) {
      78             :     scope_name_ = scope_name;
      79             :   }
      80             : #endif
      81             : 
      82             :   typedef base::ThreadedList<VariableProxy, VariableProxy::UnresolvedNext>
      83             :       UnresolvedList;
      84             : 
      85             :   DeclarationScope* AsDeclarationScope();
      86             :   const DeclarationScope* AsDeclarationScope() const;
      87             :   ModuleScope* AsModuleScope();
      88             :   const ModuleScope* AsModuleScope() const;
      89             : 
      90             :   class Snapshot final {
      91             :    public:
      92             :     Snapshot()
      93             :         : outer_scope_and_calls_eval_(nullptr, false),
      94             :           top_unresolved_(),
      95             :           top_local_() {
      96             :       DCHECK(IsCleared());
      97             :     }
      98             :     inline explicit Snapshot(Scope* scope);
      99             : 
     100     3090307 :     ~Snapshot() {
     101             :       // If we're still active, there was no arrow function. In that case outer
     102             :       // calls eval if it already called eval before this snapshot started, or
     103             :       // if the code during the snapshot called eval.
     104     6047416 :       if (!IsCleared() && outer_scope_and_calls_eval_.GetPayload()) {
     105             :         RestoreEvalFlag();
     106             :       }
     107             :     }
     108             : 
     109             :     void RestoreEvalFlag() {
     110             :       outer_scope_and_calls_eval_->scope_calls_eval_ =
     111      188050 :           outer_scope_and_calls_eval_.GetPayload();
     112             :     }
     113             : 
     114             :     void Reparent(DeclarationScope* new_parent);
     115             :     bool IsCleared() const {
     116             :       return outer_scope_and_calls_eval_.GetPointer() == nullptr;
     117             :     }
     118             : 
     119             :     void Clear() {
     120             :       outer_scope_and_calls_eval_.SetPointer(nullptr);
     121             : #ifdef DEBUG
     122             :       outer_scope_and_calls_eval_.SetPayload(false);
     123             :       top_inner_scope_ = nullptr;
     124             :       top_local_ = base::ThreadedList<Variable>::Iterator();
     125             :       top_unresolved_ = UnresolvedList::Iterator();
     126             : #endif
     127             :     }
     128             : 
     129             :    private:
     130             :     // During tracking calls_eval caches whether the outer scope called eval.
     131             :     // Upon move assignment we store whether the new inner scope calls eval into
     132             :     // the move target calls_eval bit, and restore calls eval on the outer
     133             :     // scope.
     134             :     PointerWithPayload<Scope, bool, 1> outer_scope_and_calls_eval_;
     135             :     Scope* top_inner_scope_;
     136             :     UnresolvedList::Iterator top_unresolved_;
     137             :     base::ThreadedList<Variable>::Iterator top_local_;
     138             : 
     139             :     // Disallow copy and move.
     140             :     Snapshot(const Snapshot&) = delete;
     141             :     Snapshot(Snapshot&&) = delete;
     142             :   };
     143             : 
     144             :   enum class DeserializationMode { kIncludingVariables, kScopesOnly };
     145             : 
     146             :   static Scope* DeserializeScopeChain(Isolate* isolate, Zone* zone,
     147             :                                       ScopeInfo scope_info,
     148             :                                       DeclarationScope* script_scope,
     149             :                                       AstValueFactory* ast_value_factory,
     150             :                                       DeserializationMode deserialization_mode);
     151             : 
     152             :   // Checks if the block scope is redundant, i.e. it does not contain any
     153             :   // block scoped declarations. In that case it is removed from the scope
     154             :   // tree and its children are reparented.
     155             :   Scope* FinalizeBlockScope();
     156             : 
     157             :   // Inserts outer_scope into this scope's scope chain (and removes this
     158             :   // from the current outer_scope_'s inner scope list).
     159             :   // Assumes outer_scope_ is non-null.
     160             :   void ReplaceOuterScope(Scope* outer_scope);
     161             : 
     162             :   Zone* zone() const { return zone_; }
     163             : 
     164             :   void SetMustUsePreparseData() {
     165      115121 :     if (must_use_preparsed_scope_data_) {
     166             :       return;
     167             :     }
     168       84083 :     must_use_preparsed_scope_data_ = true;
     169       84083 :     if (outer_scope_) {
     170             :       outer_scope_->SetMustUsePreparseData();
     171             :     }
     172             :   }
     173             : 
     174             :   bool must_use_preparsed_scope_data() const {
     175             :     return must_use_preparsed_scope_data_;
     176             :   }
     177             : 
     178             :   // ---------------------------------------------------------------------------
     179             :   // Declarations
     180             : 
     181             :   // Lookup a variable in this scope. Returns the variable or nullptr if not
     182             :   // found.
     183             :   Variable* LookupLocal(const AstRawString* name) {
     184             :     DCHECK(scope_info_.is_null());
     185    86366615 :     return variables_.Lookup(name);
     186             :   }
     187             : 
     188             :   Variable* LookupInScopeInfo(const AstRawString* name, Scope* cache);
     189             : 
     190             :   // Declare a local variable in this scope. If the variable has been
     191             :   // declared before, the previously declared variable is returned.
     192             :   Variable* DeclareLocal(const AstRawString* name, VariableMode mode,
     193             :                          VariableKind kind, bool* was_added,
     194             :                          InitializationFlag init_flag = kCreatedInitialized);
     195             : 
     196             :   Variable* DeclareVariable(Declaration* declaration, const AstRawString* name,
     197             :                             int pos, VariableMode mode, VariableKind kind,
     198             :                             InitializationFlag init, bool* was_added,
     199             :                             bool* sloppy_mode_block_scope_function_redefinition,
     200             :                             bool* ok);
     201             : 
     202             :   // Returns nullptr if there was a declaration conflict.
     203             :   Variable* DeclareVariableName(const AstRawString* name, VariableMode mode,
     204             :                                 bool* was_added,
     205             :                                 VariableKind kind = NORMAL_VARIABLE);
     206             :   Variable* DeclareCatchVariableName(const AstRawString* name);
     207             : 
     208             :   // Declarations list.
     209    18066914 :   base::ThreadedList<Declaration>* declarations() { return &decls_; }
     210             : 
     211             :   base::ThreadedList<Variable>* locals() { return &locals_; }
     212             : 
     213             :   // Create a new unresolved variable.
     214       96541 :   VariableProxy* NewUnresolved(AstNodeFactory* factory,
     215             :                                const AstRawString* name, int start_pos,
     216             :                                VariableKind kind = NORMAL_VARIABLE) {
     217             :     // Note that we must not share the unresolved variables with
     218             :     // the same name because they may be removed selectively via
     219             :     // RemoveUnresolved().
     220             :     DCHECK(!already_resolved_);
     221             :     DCHECK_EQ(factory->zone(), zone());
     222             :     VariableProxy* proxy = factory->NewVariableProxy(name, kind, start_pos);
     223       96541 :     AddUnresolved(proxy);
     224       96543 :     return proxy;
     225             :   }
     226             : 
     227             :   void AddUnresolved(VariableProxy* proxy);
     228             : 
     229             :   // Removes an unresolved variable from the list so it can be readded to
     230             :   // another list. This is used to reparent parameter initializers that contain
     231             :   // sloppy eval.
     232             :   bool RemoveUnresolved(VariableProxy* var);
     233             : 
     234             :   // Deletes an unresolved variable. The variable proxy cannot be reused for
     235             :   // another list later. During parsing, an unresolved variable may have been
     236             :   // added optimistically, but then only the variable name was used (typically
     237             :   // for labels and arrow function parameters). If the variable was not
     238             :   // declared, the addition introduced a new unresolved variable which may end
     239             :   // up being allocated globally as a "ghost" variable. DeleteUnresolved removes
     240             :   // such a variable again if it was added; otherwise this is a no-op.
     241             :   void DeleteUnresolved(VariableProxy* var);
     242             : 
     243             :   // Creates a new temporary variable in this scope's TemporaryScope.  The
     244             :   // name is only used for printing and cannot be used to find the variable.
     245             :   // In particular, the only way to get hold of the temporary is by keeping the
     246             :   // Variable* around.  The name should not clash with a legitimate variable
     247             :   // names.
     248             :   // TODO(verwaest): Move to DeclarationScope?
     249             :   Variable* NewTemporary(const AstRawString* name);
     250             : 
     251             :   // Find variable with (variable->mode() <= |mode_limit|) that was declared in
     252             :   // |scope|. This is used to catch patterns like `try{}catch(e){let e;}` and
     253             :   // function([e]) { let e }, which are errors even though the two 'e's are each
     254             :   // time declared in different scopes. Returns the first duplicate variable
     255             :   // name if there is one, nullptr otherwise.
     256             :   const AstRawString* FindVariableDeclaredIn(Scope* scope,
     257             :                                              VariableMode mode_limit);
     258             : 
     259             :   // ---------------------------------------------------------------------------
     260             :   // Scope-specific info.
     261             : 
     262             :   // Inform the scope and outer scopes that the corresponding code contains an
     263             :   // eval call.
     264             :   void RecordEvalCall() {
     265      147957 :     scope_calls_eval_ = true;
     266             :   }
     267             : 
     268             :   void RecordInnerScopeEvalCall() {
     269      223219 :     inner_scope_calls_eval_ = true;
     270      704206 :     for (Scope* scope = outer_scope(); scope != nullptr;
     271             :          scope = scope->outer_scope()) {
     272      530352 :       if (scope->inner_scope_calls_eval_) return;
     273      480987 :       scope->inner_scope_calls_eval_ = true;
     274             :     }
     275             :   }
     276             : 
     277             :   // Set the language mode flag (unless disabled by a global flag).
     278             :   void SetLanguageMode(LanguageMode language_mode) {
     279             :     DCHECK(!is_module_scope() || is_strict(language_mode));
     280             :     set_language_mode(language_mode);
     281             :   }
     282             : 
     283             :   // Inform the scope that the scope may execute declarations nonlinearly.
     284             :   // Currently, the only nonlinear scope is a switch statement. The name is
     285             :   // more general in case something else comes up with similar control flow,
     286             :   // for example the ability to break out of something which does not have
     287             :   // its own lexical scope.
     288             :   // The bit does not need to be stored on the ScopeInfo because none of
     289             :   // the three compilers will perform hole check elimination on a variable
     290             :   // located in VariableLocation::CONTEXT. So, direct eval and closures
     291             :   // will not expose holes.
     292      136223 :   void SetNonlinear() { scope_nonlinear_ = true; }
     293             : 
     294             :   // Position in the source where this scope begins and ends.
     295             :   //
     296             :   // * For the scope of a with statement
     297             :   //     with (obj) stmt
     298             :   //   start position: start position of first token of 'stmt'
     299             :   //   end position: end position of last token of 'stmt'
     300             :   // * For the scope of a block
     301             :   //     { stmts }
     302             :   //   start position: start position of '{'
     303             :   //   end position: end position of '}'
     304             :   // * For the scope of a function literal or decalaration
     305             :   //     function fun(a,b) { stmts }
     306             :   //   start position: start position of '('
     307             :   //   end position: end position of '}'
     308             :   // * For the scope of a catch block
     309             :   //     try { stms } catch(e) { stmts }
     310             :   //   start position: start position of '('
     311             :   //   end position: end position of ')'
     312             :   // * For the scope of a for-statement
     313             :   //     for (let x ...) stmt
     314             :   //   start position: start position of '('
     315             :   //   end position: end position of last token of 'stmt'
     316             :   // * For the scope of a switch statement
     317             :   //     switch (tag) { cases }
     318             :   //   start position: start position of '{'
     319             :   //   end position: end position of '}'
     320             :   int start_position() const { return start_position_; }
     321             :   void set_start_position(int statement_pos) {
     322    13453893 :     start_position_ = statement_pos;
     323             :   }
     324             :   int end_position() const { return end_position_; }
     325             :   void set_end_position(int statement_pos) {
     326    14138168 :     end_position_ = statement_pos;
     327             :   }
     328             : 
     329             :   // Scopes created for desugaring are hidden. I.e. not visible to the debugger.
     330      231785 :   bool is_hidden() const { return is_hidden_; }
     331      348245 :   void set_is_hidden() { is_hidden_ = true; }
     332             : 
     333             :   void ForceContextAllocationForParameters() {
     334             :     DCHECK(!already_resolved_);
     335             :     force_context_allocation_for_parameters_ = true;
     336             :   }
     337             :   bool has_forced_context_allocation_for_parameters() const {
     338     2681691 :     return force_context_allocation_for_parameters_;
     339             :   }
     340             : 
     341             :   // ---------------------------------------------------------------------------
     342             :   // Predicates.
     343             : 
     344             :   // Specific scope types.
     345    13762998 :   bool is_eval_scope() const { return scope_type_ == EVAL_SCOPE; }
     346    24336197 :   bool is_function_scope() const { return scope_type_ == FUNCTION_SCOPE; }
     347             :   bool is_module_scope() const { return scope_type_ == MODULE_SCOPE; }
     348             :   bool is_script_scope() const { return scope_type_ == SCRIPT_SCOPE; }
     349             :   bool is_catch_scope() const { return scope_type_ == CATCH_SCOPE; }
     350             :   bool is_block_scope() const { return scope_type_ == BLOCK_SCOPE; }
     351    19885271 :   bool is_with_scope() const { return scope_type_ == WITH_SCOPE; }
     352   156001203 :   bool is_declaration_scope() const { return is_declaration_scope_; }
     353             : 
     354      217987 :   bool inner_scope_calls_eval() const { return inner_scope_calls_eval_; }
     355             :   bool IsAsmModule() const;
     356             :   // Returns true if this scope or any inner scopes that might be eagerly
     357             :   // compiled are asm modules.
     358             :   bool ContainsAsmModule() const;
     359             :   // Does this scope have the potential to execute declarations non-linearly?
     360      952257 :   bool is_nonlinear() const { return scope_nonlinear_; }
     361             :   // Returns if we need to force a context because the current scope is stricter
     362             :   // than the outerscope. We need this to properly track the language mode using
     363             :   // the context. This is required in ICs where we lookup the language mode
     364             :   // from the context.
     365             :   bool ForceContextForLanguageMode() const {
     366             :     // For function scopes we need not force a context since the language mode
     367             :     // can be obtained from the closure. Script scopes always have a context.
     368     5351369 :     if (scope_type_ == FUNCTION_SCOPE || scope_type_ == SCRIPT_SCOPE) {
     369             :       return false;
     370             :     }
     371             :     DCHECK_NOT_NULL(outer_scope_);
     372     4587524 :     return (language_mode() > outer_scope_->language_mode());
     373             :   }
     374             : 
     375             :   // Whether this needs to be represented by a runtime context.
     376             :   bool NeedsContext() const {
     377             :     // Catch scopes always have heap slots.
     378             :     DCHECK_IMPLIES(is_catch_scope(), num_heap_slots() > 0);
     379             :     DCHECK_IMPLIES(is_with_scope(), num_heap_slots() > 0);
     380             :     DCHECK_IMPLIES(ForceContextForLanguageMode(), num_heap_slots() > 0);
     381     1321324 :     return num_heap_slots() > 0;
     382             :   }
     383             : 
     384             :   // Use Scope::ForEach for depth first traversal of scopes.
     385             :   // Before:
     386             :   // void Scope::VisitRecursively() {
     387             :   //   DoSomething();
     388             :   //   for (Scope* s = inner_scope_; s != nullptr; s = s->sibling_) {
     389             :   //     if (s->ShouldContinue()) continue;
     390             :   //     s->VisitRecursively();
     391             :   //   }
     392             :   // }
     393             :   //
     394             :   // After:
     395             :   // void Scope::VisitIteratively() {
     396             :   //   this->ForEach([](Scope* s) {
     397             :   //      s->DoSomething();
     398             :   //      return s->ShouldContinue() ? kContinue : kDescend;
     399             :   //   });
     400             :   // }
     401             :   template <typename FunctionType>
     402             :   V8_INLINE void ForEach(FunctionType callback);
     403             :   enum Iteration {
     404             :     // Continue the iteration on the same level, do not recurse/descent into
     405             :     // inner scopes.
     406             :     kContinue,
     407             :     // Recurse/descend into inner scopes.
     408             :     kDescend
     409             :   };
     410             : 
     411             :   // ---------------------------------------------------------------------------
     412             :   // Accessors.
     413             : 
     414             :   // The type of this scope.
     415             :   ScopeType scope_type() const { return scope_type_; }
     416             : 
     417             :   // The language mode of this scope.
     418             :   LanguageMode language_mode() const {
     419   112182706 :     return is_strict_ ? LanguageMode::kStrict : LanguageMode::kSloppy;
     420             :   }
     421             : 
     422             :   // inner_scope() and sibling() together implement the inner scope list of a
     423             :   // scope. Inner scope points to the an inner scope of the function, and
     424             :   // "sibling" points to a next inner scope of the outer scope of this scope.
     425             :   Scope* inner_scope() const { return inner_scope_; }
     426             :   Scope* sibling() const { return sibling_; }
     427             : 
     428             :   // The scope immediately surrounding this scope, or nullptr.
     429             :   Scope* outer_scope() const { return outer_scope_; }
     430             : 
     431             :   Variable* catch_variable() const {
     432             :     DCHECK(is_catch_scope());
     433             :     DCHECK_EQ(1, num_var());
     434       69459 :     return static_cast<Variable*>(variables_.Start()->value);
     435             :   }
     436             : 
     437             :   bool ShouldBanArguments();
     438             : 
     439             :   // ---------------------------------------------------------------------------
     440             :   // Variable allocation.
     441             : 
     442             :   // Result of variable allocation.
     443             :   int num_stack_slots() const { return num_stack_slots_; }
     444             :   int num_heap_slots() const { return num_heap_slots_; }
     445             : 
     446             :   int ContextLocalCount() const;
     447             : 
     448             :   // Determine if we can parse a function literal in this scope lazily without
     449             :   // caring about the unresolved variables within.
     450             :   bool AllowsLazyParsingWithoutUnresolvedVariables(const Scope* outer) const;
     451             : 
     452             :   // The number of contexts between this and scope; zero if this == scope.
     453             :   int ContextChainLength(Scope* scope) const;
     454             : 
     455             :   // The number of contexts between this and the outermost context that has a
     456             :   // sloppy eval call. One if this->calls_sloppy_eval().
     457             :   int ContextChainLengthUntilOutermostSloppyEval() const;
     458             : 
     459             :   // Find the first function, script, eval or (declaration) block scope. This is
     460             :   // the scope where var declarations will be hoisted to in the implementation.
     461             :   DeclarationScope* GetDeclarationScope();
     462             : 
     463             :   // Find the first non-block declaration scope. This should be either a script,
     464             :   // function, or eval scope. Same as DeclarationScope(), but skips declaration
     465             :   // "block" scopes. Used for differentiating associated function objects (i.e.,
     466             :   // the scope for which a function prologue allocates a context) or declaring
     467             :   // temporaries.
     468             :   DeclarationScope* GetClosureScope();
     469             :   const DeclarationScope* GetClosureScope() const;
     470             : 
     471             :   // Find the first (non-arrow) function or script scope.  This is where
     472             :   // 'this' is bound, and what determines the function kind.
     473             :   DeclarationScope* GetReceiverScope();
     474             : 
     475             :   // Find the innermost outer scope that needs a context.
     476             :   Scope* GetOuterScopeWithContext();
     477             : 
     478             :   bool HasThisReference() const;
     479             : 
     480             :   // Analyze() must have been called once to create the ScopeInfo.
     481             :   Handle<ScopeInfo> scope_info() const {
     482             :     DCHECK(!scope_info_.is_null());
     483             :     return scope_info_;
     484             :   }
     485             : 
     486    13740654 :   int num_var() const { return variables_.occupancy(); }
     487             : 
     488             :   // ---------------------------------------------------------------------------
     489             :   // Debugging.
     490             : 
     491             : #ifdef DEBUG
     492             :   void Print(int n = 0);  // n = indentation; n < 0 => don't print recursively
     493             : 
     494             :   // Check that the scope has positions assigned.
     495             :   void CheckScopePositions();
     496             : 
     497             :   // Check that all Scopes in the scope tree use the same Zone.
     498             :   void CheckZones();
     499             : #endif
     500             : 
     501             :   // Retrieve `IsSimpleParameterList` of current or outer function.
     502             :   bool HasSimpleParameters();
     503       12739 :   void set_is_debug_evaluate_scope() { is_debug_evaluate_scope_ = true; }
     504     2840367 :   bool is_debug_evaluate_scope() const { return is_debug_evaluate_scope_; }
     505             :   bool IsSkippableFunctionScope();
     506             : 
     507             :   bool RemoveInnerScope(Scope* inner_scope) {
     508             :     DCHECK_NOT_NULL(inner_scope);
     509     4431793 :     if (inner_scope == inner_scope_) {
     510     4431702 :       inner_scope_ = inner_scope_->sibling_;
     511             :       return true;
     512             :     }
     513          91 :     for (Scope* scope = inner_scope_; scope != nullptr;
     514             :          scope = scope->sibling_) {
     515          91 :       if (scope->sibling_ == inner_scope) {
     516          91 :         scope->sibling_ = scope->sibling_->sibling_;
     517             :         return true;
     518             :       }
     519             :     }
     520             :     return false;
     521             :   }
     522             : 
     523      339486 :   Variable* LookupInScopeOrScopeInfo(const AstRawString* name) {
     524      339486 :     Variable* var = variables_.Lookup(name);
     525      643887 :     if (var != nullptr || scope_info_.is_null()) return var;
     526      283123 :     return LookupInScopeInfo(name, this);
     527             :   }
     528             : 
     529             :   Variable* LookupForTesting(const AstRawString* name) {
     530       33640 :     for (Scope* scope = this; scope != nullptr; scope = scope->outer_scope()) {
     531       33640 :       Variable* var = scope->LookupInScopeOrScopeInfo(name);
     532       33640 :       if (var != nullptr) return var;
     533             :     }
     534             :     return nullptr;
     535             :   }
     536             : 
     537             :  protected:
     538             :   explicit Scope(Zone* zone);
     539             : 
     540             :   void set_language_mode(LanguageMode language_mode) {
     541    39431959 :     is_strict_ = is_strict(language_mode);
     542             :   }
     543             : 
     544             :  private:
     545             :   Variable* Declare(Zone* zone, const AstRawString* name, VariableMode mode,
     546             :                     VariableKind kind, InitializationFlag initialization_flag,
     547             :                     MaybeAssignedFlag maybe_assigned_flag, bool* was_added) {
     548             :     Variable* result =
     549    33119612 :         variables_.Declare(zone, this, name, mode, kind, initialization_flag,
     550    34058302 :                            maybe_assigned_flag, was_added);
     551    34058024 :     if (*was_added) locals_.Add(result);
     552             :     return result;
     553             :   }
     554             : 
     555             :   // This method should only be invoked on scopes created during parsing (i.e.,
     556             :   // not deserialized from a context). Also, since NeedsContext() is only
     557             :   // returning a valid result after variables are resolved, NeedsScopeInfo()
     558             :   // should also be invoked after resolution.
     559             :   bool NeedsScopeInfo() const;
     560             : 
     561             :   Variable* NewTemporary(const AstRawString* name,
     562             :                          MaybeAssignedFlag maybe_assigned);
     563             : 
     564             :   // Walk the scope chain to find DeclarationScopes; call
     565             :   // SavePreparseDataForDeclarationScope for each.
     566             :   void SavePreparseData(Parser* parser);
     567             : 
     568             :   // Create a non-local variable with a given name.
     569             :   // These variables are looked up dynamically at runtime.
     570             :   Variable* NonLocal(const AstRawString* name, VariableMode mode);
     571             : 
     572             :   enum ScopeLookupMode {
     573             :     kParsedScope,
     574             :     kDeserializedScope,
     575             :   };
     576             : 
     577             :   // Variable resolution.
     578             :   // Lookup a variable reference given by name starting with this scope, and
     579             :   // stopping when reaching the outer_scope_end scope. If the code is executed
     580             :   // because of a call to 'eval', the context parameter should be set to the
     581             :   // calling context of 'eval'.
     582             :   template <ScopeLookupMode mode>
     583             :   static Variable* Lookup(VariableProxy* proxy, Scope* scope,
     584             :                           Scope* outer_scope_end, Scope* entry_point = nullptr,
     585             :                           bool force_context_allocation = false);
     586             :   static Variable* LookupWith(VariableProxy* proxy, Scope* scope,
     587             :                               Scope* outer_scope_end, Scope* entry_point,
     588             :                               bool force_context_allocation);
     589             :   static Variable* LookupSloppyEval(VariableProxy* proxy, Scope* scope,
     590             :                                     Scope* outer_scope_end, Scope* entry_point,
     591             :                                     bool force_context_allocation);
     592             :   static bool ResolvePreparsedVariable(VariableProxy* proxy, Scope* scope,
     593             :                                        Scope* end);
     594             :   void ResolveTo(ParseInfo* info, VariableProxy* proxy, Variable* var);
     595             :   V8_WARN_UNUSED_RESULT bool ResolveVariable(ParseInfo* info,
     596             :                                              VariableProxy* proxy);
     597             :   V8_WARN_UNUSED_RESULT bool ResolveVariablesRecursively(ParseInfo* info);
     598             : 
     599             :   // Finds free variables of this scope. This mutates the unresolved variables
     600             :   // list along the way, so full resolution cannot be done afterwards.
     601             :   void AnalyzePartially(DeclarationScope* max_outer_scope,
     602             :                         AstNodeFactory* ast_node_factory,
     603             :                         UnresolvedList* new_unresolved_list);
     604             :   void CollectNonLocals(DeclarationScope* max_outer_scope, Isolate* isolate,
     605             :                         ParseInfo* info, Handle<StringSet>* non_locals);
     606             : 
     607             :   // Predicates.
     608             :   bool MustAllocate(Variable* var);
     609             :   bool MustAllocateInContext(Variable* var);
     610             : 
     611             :   // Variable allocation.
     612             :   void AllocateStackSlot(Variable* var);
     613             :   V8_INLINE void AllocateHeapSlot(Variable* var);
     614             :   void AllocateNonParameterLocal(Variable* var);
     615             :   void AllocateDeclaredGlobal(Variable* var);
     616             :   V8_INLINE void AllocateNonParameterLocalsAndDeclaredGlobals();
     617             :   void AllocateVariablesRecursively();
     618             : 
     619             :   void AllocateScopeInfosRecursively(Isolate* isolate,
     620             :                                      MaybeHandle<ScopeInfo> outer_scope);
     621             : 
     622             :   void AllocateDebuggerScopeInfos(Isolate* isolate,
     623             :                                   MaybeHandle<ScopeInfo> outer_scope);
     624             : 
     625             :   // Construct a scope based on the scope info.
     626             :   Scope(Zone* zone, ScopeType type, Handle<ScopeInfo> scope_info);
     627             : 
     628             :   // Construct a catch scope with a binding for the name.
     629             :   Scope(Zone* zone, const AstRawString* catch_variable_name,
     630             :         MaybeAssignedFlag maybe_assigned, Handle<ScopeInfo> scope_info);
     631             : 
     632             :   void AddInnerScope(Scope* inner_scope) {
     633    13986494 :     inner_scope->sibling_ = inner_scope_;
     634    13986494 :     inner_scope_ = inner_scope;
     635    13986494 :     inner_scope->outer_scope_ = this;
     636             :   }
     637             : 
     638             :   void SetDefaults();
     639             : 
     640             :   friend class DeclarationScope;
     641             :   friend class ScopeTestHelper;
     642             : 
     643             :   Zone* zone_;
     644             : 
     645             :   // Scope tree.
     646             :   Scope* outer_scope_;  // the immediately enclosing outer scope, or nullptr
     647             :   Scope* inner_scope_;  // an inner scope of this scope
     648             :   Scope* sibling_;  // a sibling inner scope of the outer scope of this scope.
     649             : 
     650             :   // The variables declared in this scope:
     651             :   //
     652             :   // All user-declared variables (incl. parameters).  For script scopes
     653             :   // variables may be implicitly 'declared' by being used (possibly in
     654             :   // an inner scope) with no intervening with statements or eval calls.
     655             :   VariableMap variables_;
     656             :   // In case of non-scopeinfo-backed scopes, this contains the variables of the
     657             :   // map above in order of addition.
     658             :   base::ThreadedList<Variable> locals_;
     659             :   // Unresolved variables referred to from this scope. The proxies themselves
     660             :   // form a linked list of all unresolved proxies.
     661             :   UnresolvedList unresolved_list_;
     662             :   // Declarations.
     663             :   base::ThreadedList<Declaration> decls_;
     664             : 
     665             :   // Serialized scope info support.
     666             :   Handle<ScopeInfo> scope_info_;
     667             : // Debugging support.
     668             : #ifdef DEBUG
     669             :   const AstRawString* scope_name_;
     670             : 
     671             :   // True if it doesn't need scope resolution (e.g., if the scope was
     672             :   // constructed based on a serialized scope info or a catch context).
     673             :   bool already_resolved_;
     674             :   // True if this scope may contain objects from a temp zone that needs to be
     675             :   // fixed up.
     676             :   bool needs_migration_;
     677             : #endif
     678             : 
     679             :   // Source positions.
     680             :   int start_position_;
     681             :   int end_position_;
     682             : 
     683             :   // Computed via AllocateVariables.
     684             :   int num_stack_slots_;
     685             :   int num_heap_slots_;
     686             : 
     687             :   // The scope type.
     688             :   const ScopeType scope_type_;
     689             : 
     690             :   // Scope-specific information computed during parsing.
     691             :   //
     692             :   // The language mode of this scope.
     693             :   STATIC_ASSERT(LanguageModeSize == 2);
     694             :   bool is_strict_ : 1;
     695             :   // This scope or a nested catch scope or with scope contain an 'eval' call. At
     696             :   // the 'eval' call site this scope is the declaration scope.
     697             :   bool scope_calls_eval_ : 1;
     698             :   // This scope's declarations might not be executed in order (e.g., switch).
     699             :   bool scope_nonlinear_ : 1;
     700             :   bool is_hidden_ : 1;
     701             :   // Temporary workaround that allows masking of 'this' in debug-evalute scopes.
     702             :   bool is_debug_evaluate_scope_ : 1;
     703             : 
     704             :   // True if one of the inner scopes or the scope itself calls eval.
     705             :   bool inner_scope_calls_eval_ : 1;
     706             :   bool force_context_allocation_ : 1;
     707             :   bool force_context_allocation_for_parameters_ : 1;
     708             : 
     709             :   // True if it holds 'var' declarations.
     710             :   bool is_declaration_scope_ : 1;
     711             : 
     712             :   bool must_use_preparsed_scope_data_ : 1;
     713             : };
     714             : 
     715           1 : class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
     716             :  public:
     717             :   DeclarationScope(Zone* zone, Scope* outer_scope, ScopeType scope_type,
     718             :                    FunctionKind function_kind = kNormalFunction);
     719             :   DeclarationScope(Zone* zone, ScopeType scope_type,
     720             :                    Handle<ScopeInfo> scope_info);
     721             :   // Creates a script scope.
     722             :   DeclarationScope(Zone* zone, AstValueFactory* ast_value_factory);
     723             : 
     724      274309 :   FunctionKind function_kind() const { return function_kind_; }
     725             : 
     726             :   bool is_arrow_scope() const {
     727    18515101 :     return is_function_scope() && IsArrowFunction(function_kind_);
     728             :   }
     729             : 
     730             :   // Inform the scope that the corresponding code uses "super".
     731             :   void RecordSuperPropertyUsage() {
     732             :     DCHECK(IsConciseMethod(function_kind()) ||
     733             :            IsAccessorFunction(function_kind()) ||
     734             :            IsClassConstructor(function_kind()));
     735        7214 :     scope_uses_super_property_ = true;
     736             :   }
     737             : 
     738             :   // Does this scope access "super" property (super.foo).
     739     3899964 :   bool NeedsHomeObject() const {
     740     7797345 :     return scope_uses_super_property_ ||
     741     4393699 :            (inner_scope_calls_eval_ && (IsConciseMethod(function_kind()) ||
     742      244640 :                                         IsAccessorFunction(function_kind()) ||
     743     3899964 :                                         IsClassConstructor(function_kind())));
     744             :   }
     745             : 
     746             :   bool calls_sloppy_eval() const {
     747             :     // TODO(delphick): Calculate this when setting and change the name of
     748             :     // scope_calls_eval_.
     749    22452708 :     return !is_script_scope() && scope_calls_eval_ &&
     750             :            is_sloppy(language_mode());
     751             :   }
     752             : 
     753    12151547 :   bool was_lazily_parsed() const { return was_lazily_parsed_; }
     754             : 
     755             :   Variable* LookupInModule(const AstRawString* name) {
     756             :     DCHECK(is_module_scope());
     757         140 :     Variable* var = variables_.Lookup(name);
     758             :     DCHECK_NOT_NULL(var);
     759             :     return var;
     760             :   }
     761             : 
     762             :   void DeserializeReceiver(AstValueFactory* ast_value_factory);
     763             : 
     764             : #ifdef DEBUG
     765             :   void set_is_being_lazily_parsed(bool is_being_lazily_parsed) {
     766             :     is_being_lazily_parsed_ = is_being_lazily_parsed;
     767             :   }
     768             :   bool is_being_lazily_parsed() const { return is_being_lazily_parsed_; }
     769             : #endif
     770             :   void set_zone(Zone* zone) {
     771             : #ifdef DEBUG
     772             :     needs_migration_ = true;
     773             : #endif
     774     2603261 :     zone_ = zone;
     775             :   }
     776             : 
     777             :   // ---------------------------------------------------------------------------
     778             :   // Illegal redeclaration support.
     779             : 
     780             :   // Check if the scope has conflicting var
     781             :   // declarations, i.e. a var declaration that has been hoisted from a nested
     782             :   // scope over a let binding of the same name.
     783             :   Declaration* CheckConflictingVarDeclarations();
     784             : 
     785             :   void set_has_checked_syntax(bool has_checked_syntax) {
     786      178218 :     has_checked_syntax_ = has_checked_syntax;
     787             :   }
     788     2118167 :   bool has_checked_syntax() const { return has_checked_syntax_; }
     789             : 
     790             :   bool ShouldEagerCompile() const {
     791     9161182 :     return force_eager_compilation_ || should_eager_compile_;
     792             :   }
     793             : 
     794             :   void set_should_eager_compile();
     795             : 
     796             :   void SetScriptScopeInfo(Handle<ScopeInfo> scope_info) {
     797             :     DCHECK(is_script_scope());
     798             :     DCHECK(scope_info_.is_null());
     799     1014550 :     scope_info_ = scope_info;
     800             :   }
     801             : 
     802     3614824 :   bool is_asm_module() const { return is_asm_module_; }
     803             :   void set_is_asm_module();
     804             : 
     805             :   bool should_ban_arguments() const {
     806             :     return IsClassMembersInitializerFunction(function_kind());
     807             :   }
     808             : 
     809             :   void DeclareThis(AstValueFactory* ast_value_factory);
     810             :   void DeclareArguments(AstValueFactory* ast_value_factory);
     811             :   void DeclareDefaultFunctionVariables(AstValueFactory* ast_value_factory);
     812             : 
     813             :   // Declare the function variable for a function literal. This variable
     814             :   // is in an intermediate scope between this function scope and the the
     815             :   // outer scope. Only possible for function scopes; at most one variable.
     816             :   //
     817             :   // This function needs to be called after all other variables have been
     818             :   // declared in the scope. It will add a variable for {name} to {variables_};
     819             :   // either the function variable itself, or a non-local in case the function
     820             :   // calls sloppy eval.
     821             :   Variable* DeclareFunctionVar(const AstRawString* name,
     822             :                                Scope* cache = nullptr);
     823             : 
     824             :   // Declare some special internal variables which must be accessible to
     825             :   // Ignition without ScopeInfo.
     826             :   Variable* DeclareGeneratorObjectVar(const AstRawString* name);
     827             : 
     828             :   // Declare a parameter in this scope.  When there are duplicated
     829             :   // parameters the rightmost one 'wins'.  However, the implementation
     830             :   // expects all parameters to be declared and from left to right.
     831             :   Variable* DeclareParameter(const AstRawString* name, VariableMode mode,
     832             :                              bool is_optional, bool is_rest,
     833             :                              AstValueFactory* ast_value_factory, int position);
     834             : 
     835             :   // Makes sure that num_parameters_ and has_rest is correct for the preparser.
     836             :   void RecordParameter(bool is_rest);
     837             : 
     838             :   // Declare an implicit global variable in this scope which must be a
     839             :   // script scope.  The variable was introduced (possibly from an inner
     840             :   // scope) by a reference to an unresolved variable with no intervening
     841             :   // with statements or eval calls.
     842             :   Variable* DeclareDynamicGlobal(const AstRawString* name,
     843             :                                  VariableKind variable_kind, Scope* cache);
     844             : 
     845             :   // The variable corresponding to the 'this' value.
     846             :   Variable* receiver() {
     847             :     DCHECK(has_this_declaration() || is_script_scope());
     848             :     DCHECK_NOT_NULL(receiver_);
     849             :     return receiver_;
     850             :   }
     851             : 
     852    16189889 :   bool has_this_declaration() const { return has_this_declaration_; }
     853             : 
     854             :   // The variable corresponding to the 'new.target' value.
     855             :   Variable* new_target_var() { return new_target_; }
     856             : 
     857             :   // The variable holding the function literal for named function
     858             :   // literals, or nullptr.  Only valid for function scopes.
     859             :   Variable* function_var() const { return function_; }
     860             : 
     861             :   // The variable holding the JSGeneratorObject for generator, async
     862             :   // and async generator functions, and modules. Only valid for
     863             :   // function and module scopes.
     864             :   Variable* generator_object_var() const {
     865             :     DCHECK(is_function_scope() || is_module_scope());
     866             :     return GetRareVariable(RareVariable::kGeneratorObject);
     867             :   }
     868             : 
     869             :   // Parameters. The left-most parameter has index 0.
     870             :   // Only valid for function and module scopes.
     871             :   Variable* parameter(int index) const {
     872             :     DCHECK(is_function_scope() || is_module_scope());
     873             :     DCHECK(!is_being_lazily_parsed_);
     874     2486835 :     return params_[index];
     875             :   }
     876             : 
     877             :   // Returns the number of formal parameters, excluding a possible rest
     878             :   // parameter.  Examples:
     879             :   //   function foo(a, b) {}         ==> 2
     880             :   //   function foo(a, b, ...c) {}   ==> 2
     881             :   //   function foo(a, b, c = 1) {}  ==> 3
     882             :   int num_parameters() const { return num_parameters_; }
     883             : 
     884             :   // The function's rest parameter (nullptr if there is none).
     885             :   Variable* rest_parameter() const {
     886     2729040 :     return has_rest_ ? params_[params_.length() - 1] : nullptr;
     887             :   }
     888             : 
     889     2311944 :   bool has_simple_parameters() const { return has_simple_parameters_; }
     890             : 
     891             :   // TODO(caitp): manage this state in a better way. PreParser must be able to
     892             :   // communicate that the scope is non-simple, without allocating any parameters
     893             :   // as the Parser does. This is necessary to ensure that TC39's proposed early
     894             :   // error can be reported consistently regardless of whether lazily parsed or
     895             :   // not.
     896             :   void SetHasNonSimpleParameters() {
     897             :     DCHECK(is_function_scope());
     898      242687 :     has_simple_parameters_ = false;
     899             :   }
     900             : 
     901       56622 :   void MakeParametersNonSimple() {
     902             :     SetHasNonSimpleParameters();
     903      312962 :     for (ZoneHashMap::Entry* p = variables_.Start(); p != nullptr;
     904             :          p = variables_.Next(p)) {
     905      128170 :       Variable* var = reinterpret_cast<Variable*>(p->value);
     906      128170 :       if (var->is_parameter()) var->MakeParameterNonSimple();
     907             :     }
     908       56622 :   }
     909             : 
     910             :   // Returns whether the arguments object aliases formal parameters.
     911             :   CreateArgumentsType GetArgumentsType() const {
     912             :     DCHECK(is_function_scope());
     913             :     DCHECK(!is_arrow_scope());
     914             :     DCHECK_NOT_NULL(arguments_);
     915             :     return is_sloppy(language_mode()) && has_simple_parameters()
     916             :                ? CreateArgumentsType::kMappedArguments
     917      357332 :                : CreateArgumentsType::kUnmappedArguments;
     918             :   }
     919             : 
     920             :   // The local variable 'arguments' if we need to allocate it; nullptr
     921             :   // otherwise.
     922             :   Variable* arguments() const {
     923             :     DCHECK_IMPLIES(is_arrow_scope(), arguments_ == nullptr);
     924             :     return arguments_;
     925             :   }
     926             : 
     927             :   Variable* this_function_var() const {
     928             :     Variable* this_function = GetRareVariable(RareVariable::kThisFunction);
     929             : 
     930             :     // This is only used in derived constructors atm.
     931             :     DCHECK(this_function == nullptr ||
     932             :            (is_function_scope() && (IsClassConstructor(function_kind()) ||
     933             :                                     IsConciseMethod(function_kind()) ||
     934             :                                     IsAccessorFunction(function_kind()))));
     935             :     return this_function;
     936             :   }
     937             : 
     938             :   // Adds a local variable in this scope's locals list. This is for adjusting
     939             :   // the scope of temporaries and do-expression vars when desugaring parameter
     940             :   // initializers.
     941             :   void AddLocal(Variable* var);
     942             : 
     943             :   void DeclareSloppyBlockFunction(
     944             :       SloppyBlockFunctionStatement* sloppy_block_function);
     945             : 
     946             :   // Go through sloppy_block_functions_ and hoist those (into this scope)
     947             :   // which should be hoisted.
     948             :   void HoistSloppyBlockFunctions(AstNodeFactory* factory);
     949             : 
     950             :   // Compute top scope and allocate variables. For lazy compilation the top
     951             :   // scope only contains the single lazily compiled function, so this
     952             :   // doesn't re-allocate variables repeatedly.
     953             :   //
     954             :   // Returns false if private names can not be resolved and
     955             :   // ParseInfo's pending_error_handler will be populated with an
     956             :   // error. Otherwise, returns true.
     957             :   V8_WARN_UNUSED_RESULT
     958             :   static bool Analyze(ParseInfo* info);
     959             : 
     960             :   // To be called during parsing. Do just enough scope analysis that we can
     961             :   // discard the Scope contents for lazily compiled functions. In particular,
     962             :   // this records variables which cannot be resolved inside the Scope (we don't
     963             :   // yet know what they will resolve to since the outer Scopes are incomplete)
     964             :   // and recreates them with the correct Zone with ast_node_factory.
     965             :   void AnalyzePartially(Parser* parser, AstNodeFactory* ast_node_factory);
     966             : 
     967             :   // Allocate ScopeInfos for top scope and any inner scopes that need them.
     968             :   // Does nothing if ScopeInfo is already allocated.
     969             :   static void AllocateScopeInfos(ParseInfo* info, Isolate* isolate);
     970             : 
     971             :   Handle<StringSet> CollectNonLocals(Isolate* isolate, ParseInfo* info,
     972             :                                      Handle<StringSet> non_locals);
     973             : 
     974             :   // Determine if we can use lazy compilation for this scope.
     975             :   bool AllowsLazyCompilation() const;
     976             : 
     977             :   // Make sure this closure and all outer closures are eagerly compiled.
     978             :   void ForceEagerCompilation() {
     979             :     DCHECK_EQ(this, GetClosureScope());
     980             :     DeclarationScope* s;
     981        1829 :     for (s = this; !s->is_script_scope();
     982             :          s = s->outer_scope()->GetClosureScope()) {
     983           5 :       s->force_eager_compilation_ = true;
     984             :     }
     985        1819 :     s->force_eager_compilation_ = true;
     986             :   }
     987             : 
     988             : #ifdef DEBUG
     989             :   void PrintParameters();
     990             : #endif
     991             : 
     992             :   V8_INLINE void AllocateLocals();
     993             :   V8_INLINE void AllocateParameterLocals();
     994             :   V8_INLINE void AllocateReceiver();
     995             : 
     996             :   void ResetAfterPreparsing(AstValueFactory* ast_value_factory, bool aborted);
     997             : 
     998      283937 :   bool is_skipped_function() const { return is_skipped_function_; }
     999             :   void set_is_skipped_function(bool is_skipped_function) {
    1000       60666 :     is_skipped_function_ = is_skipped_function;
    1001             :   }
    1002             : 
    1003             :   bool has_inferred_function_name() const {
    1004             :     return has_inferred_function_name_;
    1005             :   }
    1006             :   void set_has_inferred_function_name(bool value) {
    1007             :     DCHECK(is_function_scope());
    1008     1176863 :     has_inferred_function_name_ = value;
    1009             :   }
    1010             : 
    1011             :   // Save data describing the context allocation of the variables in this scope
    1012             :   // and its subscopes (except scopes at the laziness boundary). The data is
    1013             :   // saved in produced_preparse_data_.
    1014             :   void SavePreparseDataForDeclarationScope(Parser* parser);
    1015             : 
    1016             :   void set_preparse_data_builder(PreparseDataBuilder* preparse_data_builder) {
    1017     2660304 :     preparse_data_builder_ = preparse_data_builder;
    1018             :   }
    1019             : 
    1020             :   PreparseDataBuilder* preparse_data_builder() const {
    1021             :     return preparse_data_builder_;
    1022             :   }
    1023             : 
    1024      128535 :   void set_has_this_reference() { has_this_reference_ = true; }
    1025        3557 :   bool has_this_reference() const { return has_this_reference_; }
    1026             :   void UsesThis() {
    1027             :     set_has_this_reference();
    1028         102 :     GetReceiverScope()->receiver()->ForceContextAllocation();
    1029             :   }
    1030             : 
    1031             :  private:
    1032             :   V8_INLINE void AllocateParameter(Variable* var, int index);
    1033             : 
    1034             :   // Resolve and fill in the allocation information for all variables
    1035             :   // in this scopes. Must be called *after* all scopes have been
    1036             :   // processed (parsed) to ensure that unresolved variables can be
    1037             :   // resolved properly.
    1038             :   //
    1039             :   // In the case of code compiled and run using 'eval', the context
    1040             :   // parameter is the context in which eval was called.  In all other
    1041             :   // cases the context parameter is an empty handle.
    1042             :   //
    1043             :   // Returns false if private names can not be resolved.
    1044             :   bool AllocateVariables(ParseInfo* info);
    1045             : 
    1046             :   void SetDefaults();
    1047             : 
    1048             :   bool has_simple_parameters_ : 1;
    1049             :   // This scope contains an "use asm" annotation.
    1050             :   bool is_asm_module_ : 1;
    1051             :   bool force_eager_compilation_ : 1;
    1052             :   // This function scope has a rest parameter.
    1053             :   bool has_rest_ : 1;
    1054             :   // This scope has a parameter called "arguments".
    1055             :   bool has_arguments_parameter_ : 1;
    1056             :   // This scope uses "super" property ('super.foo').
    1057             :   bool scope_uses_super_property_ : 1;
    1058             :   bool should_eager_compile_ : 1;
    1059             :   // Set to true after we have finished lazy parsing the scope.
    1060             :   bool was_lazily_parsed_ : 1;
    1061             : #if DEBUG
    1062             :   bool is_being_lazily_parsed_ : 1;
    1063             : #endif
    1064             :   bool is_skipped_function_ : 1;
    1065             :   bool has_inferred_function_name_ : 1;
    1066             :   bool has_checked_syntax_ : 1;
    1067             :   bool has_this_reference_ : 1;
    1068             :   bool has_this_declaration_ : 1;
    1069             : 
    1070             :   // If the scope is a function scope, this is the function kind.
    1071             :   const FunctionKind function_kind_;
    1072             : 
    1073             :   int num_parameters_ = 0;
    1074             : 
    1075             :   // Parameter list in source order.
    1076             :   ZonePtrList<Variable> params_;
    1077             :   // Map of function names to lists of functions defined in sloppy blocks
    1078             :   base::ThreadedList<SloppyBlockFunctionStatement> sloppy_block_functions_;
    1079             :   // Convenience variable.
    1080             :   Variable* receiver_;
    1081             :   // Function variable, if any; function scopes only.
    1082             :   Variable* function_;
    1083             :   // new.target variable, function scopes only.
    1084             :   Variable* new_target_;
    1085             :   // Convenience variable; function scopes only.
    1086             :   Variable* arguments_;
    1087             : 
    1088             :   // For producing the scope allocation data during preparsing.
    1089             :   PreparseDataBuilder* preparse_data_builder_;
    1090             : 
    1091     1069323 :   struct RareData : public ZoneObject {
    1092             :     // Convenience variable; Subclass constructor only
    1093             :     Variable* this_function = nullptr;
    1094             : 
    1095             :     // Generator object, if any; generator function scopes and module scopes
    1096             :     // only.
    1097             :     Variable* generator_object = nullptr;
    1098             :   };
    1099             : 
    1100             :   enum class RareVariable {
    1101             :     kThisFunction = offsetof(RareData, this_function),
    1102             :     kGeneratorObject = offsetof(RareData, generator_object),
    1103             :   };
    1104             : 
    1105             :   V8_INLINE RareData* EnsureRareData() {
    1106     1081658 :     if (rare_data_ == nullptr) {
    1107     2138649 :       rare_data_ = new (zone_) RareData;
    1108             :     }
    1109     1081655 :     return rare_data_;
    1110             :   }
    1111             : 
    1112             :   V8_INLINE Variable* GetRareVariable(RareVariable id) const {
    1113     2303804 :     if (rare_data_ == nullptr) return nullptr;
    1114             :     return *reinterpret_cast<Variable**>(
    1115      351671 :         reinterpret_cast<uint8_t*>(rare_data_) + static_cast<ptrdiff_t>(id));
    1116             :   }
    1117             : 
    1118             :   // Set `var` to null if it's non-null and Predicate (Variable*) -> bool
    1119             :   // returns true.
    1120             :   template <typename Predicate>
    1121             :   V8_INLINE void NullifyRareVariableIf(RareVariable id, Predicate predicate) {
    1122     2702890 :     if (V8_LIKELY(rare_data_ == nullptr)) return;
    1123             :     Variable** var = reinterpret_cast<Variable**>(
    1124             :         reinterpret_cast<uint8_t*>(rare_data_) + static_cast<ptrdiff_t>(id));
    1125      364879 :     if (*var && predicate(*var)) *var = nullptr;
    1126             :   }
    1127             : 
    1128             :   RareData* rare_data_ = nullptr;
    1129             : };
    1130             : 
    1131     3090298 : Scope::Snapshot::Snapshot(Scope* scope)
    1132     3090298 :     : outer_scope_and_calls_eval_(scope, scope->scope_calls_eval_),
    1133     3090298 :       top_inner_scope_(scope->inner_scope_),
    1134             :       top_unresolved_(scope->unresolved_list_.end()),
    1135     3090298 :       top_local_(scope->GetClosureScope()->locals_.end()) {
    1136             :   // Reset in order to record eval calls during this Snapshot's lifetime.
    1137     3090296 :   outer_scope_and_calls_eval_.GetPointer()->scope_calls_eval_ = false;
    1138     3090296 : }
    1139             : 
    1140             : class ModuleScope final : public DeclarationScope {
    1141             :  public:
    1142             :   ModuleScope(DeclarationScope* script_scope, AstValueFactory* avfactory);
    1143             : 
    1144             :   // Deserialization. Does not restore the module descriptor.
    1145             :   ModuleScope(Isolate* isolate, Handle<ScopeInfo> scope_info,
    1146             :               AstValueFactory* avfactory);
    1147             : 
    1148             :   // Returns nullptr in a deserialized scope.
    1149             :   ModuleDescriptor* module() const { return module_descriptor_; }
    1150             : 
    1151             :   // Set MODULE as VariableLocation for all variables that will live in a
    1152             :   // module's export table.
    1153             :   void AllocateModuleVariables();
    1154             : 
    1155             :  private:
    1156             :   ModuleDescriptor* const module_descriptor_;
    1157             : };
    1158             : 
    1159             : }  // namespace internal
    1160             : }  // namespace v8
    1161             : 
    1162             : #endif  // V8_AST_SCOPES_H_

Generated by: LCOV version 1.10