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

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

Generated by: LCOV version 1.10