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

Generated by: LCOV version 1.10