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

Generated by: LCOV version 1.10