LCOV - code coverage report
Current view: top level - src/ast - scopes.h (source / functions) Hit Total Coverage
Test: app.info Lines: 92 92 100.0 %
Date: 2017-04-26 Functions: 10 10 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/base/compiler-specific.h"
       9             : #include "src/base/hashmap.h"
      10             : #include "src/globals.h"
      11             : #include "src/objects.h"
      12             : #include "src/zone/zone.h"
      13             : 
      14             : namespace v8 {
      15             : namespace internal {
      16             : 
      17             : class AstNodeFactory;
      18             : class AstValueFactory;
      19             : class AstRawString;
      20             : class Declaration;
      21             : class ParseInfo;
      22             : class PreParsedScopeData;
      23             : class SloppyBlockFunctionStatement;
      24             : class Statement;
      25             : class StringSet;
      26             : class VariableProxy;
      27             : 
      28             : // A hash map to support fast variable declaration and lookup.
      29             : class VariableMap: public ZoneHashMap {
      30             :  public:
      31             :   explicit VariableMap(Zone* zone);
      32             : 
      33             :   Variable* Declare(
      34             :       Zone* zone, Scope* scope, const AstRawString* name, VariableMode mode,
      35             :       VariableKind kind = NORMAL_VARIABLE,
      36             :       InitializationFlag initialization_flag = kCreatedInitialized,
      37             :       MaybeAssignedFlag maybe_assigned_flag = kNotAssigned,
      38             :       bool* added = nullptr);
      39             : 
      40             :   // Records that "name" exists (if not recorded yet) but doesn't create a
      41             :   // Variable. Useful for preparsing.
      42             :   Variable* DeclareName(Zone* zone, const AstRawString* name,
      43             :                         VariableMode mode);
      44             : 
      45             :   Variable* Lookup(const AstRawString* name);
      46             :   void Remove(Variable* var);
      47             :   void Add(Zone* zone, Variable* var);
      48             : };
      49             : 
      50             : 
      51             : // Sloppy block-scoped function declarations to var-bind
      52             : class SloppyBlockFunctionMap : public ZoneHashMap {
      53             :  public:
      54             :   class Delegate : public ZoneObject {
      55             :    public:
      56             :     Delegate(Scope* scope, SloppyBlockFunctionStatement* statement, int index)
      57       12027 :         : scope_(scope), statement_(statement), next_(nullptr), index_(index) {}
      58             :     void set_statement(Statement* statement);
      59       12027 :     void set_next(Delegate* next) { next_ = next; }
      60             :     Delegate* next() const { return next_; }
      61             :     Scope* scope() const { return scope_; }
      62             :     int index() const { return index_; }
      63             : 
      64             :    private:
      65             :     Scope* scope_;
      66             :     SloppyBlockFunctionStatement* statement_;
      67             :     Delegate* next_;
      68             :     int index_;
      69             :   };
      70             : 
      71             :   explicit SloppyBlockFunctionMap(Zone* zone);
      72             :   void Declare(Zone* zone, const AstRawString* name, Scope* scope,
      73             :                SloppyBlockFunctionStatement* statement);
      74             : 
      75             :  private:
      76             :   int count_;
      77             : };
      78             : 
      79             : enum class AnalyzeMode { kRegular, kDebugger };
      80             : 
      81             : // Global invariants after AST construction: Each reference (i.e. identifier)
      82             : // to a JavaScript variable (including global properties) is represented by a
      83             : // VariableProxy node. Immediately after AST construction and before variable
      84             : // allocation, most VariableProxy nodes are "unresolved", i.e. not bound to a
      85             : // corresponding variable (though some are bound during parse time). Variable
      86             : // allocation binds each unresolved VariableProxy to one Variable and assigns
      87             : // a location. Note that many VariableProxy nodes may refer to the same Java-
      88             : // Script variable.
      89             : 
      90             : // JS environments are represented in the parser using Scope, DeclarationScope
      91             : // and ModuleScope. DeclarationScope is used for any scope that hosts 'var'
      92             : // declarations. This includes script, module, eval, varblock, and function
      93             : // scope. ModuleScope further specializes DeclarationScope.
      94             : class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
      95             :  public:
      96             :   // ---------------------------------------------------------------------------
      97             :   // Construction
      98             : 
      99             :   Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type);
     100             : 
     101             : #ifdef DEBUG
     102             :   // The scope name is only used for printing/debugging.
     103             :   void SetScopeName(const AstRawString* scope_name) {
     104             :     scope_name_ = scope_name;
     105             :   }
     106             :   void set_needs_migration() { needs_migration_ = true; }
     107             : #endif
     108             : 
     109             :   // TODO(verwaest): Is this needed on Scope?
     110             :   int num_parameters() const;
     111             : 
     112             :   DeclarationScope* AsDeclarationScope();
     113             :   const DeclarationScope* AsDeclarationScope() const;
     114             :   ModuleScope* AsModuleScope();
     115             :   const ModuleScope* AsModuleScope() const;
     116             : 
     117             :   class Snapshot final BASE_EMBEDDED {
     118             :    public:
     119             :     explicit Snapshot(Scope* scope);
     120             :     ~Snapshot();
     121             : 
     122             :     void Reparent(DeclarationScope* new_parent) const;
     123             : 
     124             :    private:
     125             :     Scope* outer_scope_;
     126             :     Scope* top_inner_scope_;
     127             :     VariableProxy* top_unresolved_;
     128             :     ThreadedList<Variable>::Iterator top_local_;
     129             :     ThreadedList<Declaration>::Iterator top_decl_;
     130             :     const bool outer_scope_calls_eval_;
     131             :   };
     132             : 
     133             :   enum class DeserializationMode { kIncludingVariables, kScopesOnly };
     134             : 
     135             :   static Scope* DeserializeScopeChain(Zone* zone, ScopeInfo* scope_info,
     136             :                                       DeclarationScope* script_scope,
     137             :                                       AstValueFactory* ast_value_factory,
     138             :                                       DeserializationMode deserialization_mode);
     139             : 
     140             :   // Checks if the block scope is redundant, i.e. it does not contain any
     141             :   // block scoped declarations. In that case it is removed from the scope
     142             :   // tree and its children are reparented.
     143             :   Scope* FinalizeBlockScope();
     144             : 
     145             :   bool HasBeenRemoved() const;
     146             : 
     147             :   // Find the first scope that hasn't been removed.
     148             :   Scope* GetUnremovedScope();
     149             : 
     150             :   // Inserts outer_scope into this scope's scope chain (and removes this
     151             :   // from the current outer_scope_'s inner scope list).
     152             :   // Assumes outer_scope_ is non-null.
     153             :   void ReplaceOuterScope(Scope* outer_scope);
     154             : 
     155     9965353 :   Zone* zone() const { return zone_; }
     156             : 
     157             :   void SetMustUsePreParsedScopeData() {
     158          28 :     if (must_use_preparsed_scope_data_) {
     159             :       return;
     160             :     }
     161          14 :     must_use_preparsed_scope_data_ = true;
     162          14 :     if (outer_scope_) {
     163             :       outer_scope_->SetMustUsePreParsedScopeData();
     164             :     }
     165             :   }
     166             : 
     167             :   bool must_use_preparsed_scope_data() const {
     168             :     return must_use_preparsed_scope_data_;
     169             :   }
     170             : 
     171             :   // ---------------------------------------------------------------------------
     172             :   // Declarations
     173             : 
     174             :   // Lookup a variable in this scope. Returns the variable or NULL if not found.
     175   134835063 :   Variable* LookupLocal(const AstRawString* name) {
     176   134835063 :     Variable* result = variables_.Lookup(name);
     177   187656000 :     if (result != nullptr || scope_info_.is_null()) return result;
     178     2521334 :     return LookupInScopeInfo(name);
     179             :   }
     180             : 
     181             :   Variable* LookupInScopeInfo(const AstRawString* name);
     182             : 
     183             :   // Lookup a variable in this scope or outer scopes.
     184             :   // Returns the variable or NULL if not found.
     185             :   Variable* Lookup(const AstRawString* name);
     186             : 
     187             :   // Declare a local variable in this scope. If the variable has been
     188             :   // declared before, the previously declared variable is returned.
     189             :   Variable* DeclareLocal(const AstRawString* name, VariableMode mode,
     190             :                          InitializationFlag init_flag = kCreatedInitialized,
     191             :                          VariableKind kind = NORMAL_VARIABLE,
     192             :                          MaybeAssignedFlag maybe_assigned_flag = kNotAssigned);
     193             : 
     194             :   Variable* DeclareVariable(Declaration* declaration, VariableMode mode,
     195             :                             InitializationFlag init,
     196             :                             bool allow_harmony_restrictive_generators,
     197             :                             bool* sloppy_mode_block_scope_function_redefinition,
     198             :                             bool* ok);
     199             : 
     200             :   // The return value is meaningful only if FLAG_preparser_scope_analysis is on.
     201             :   Variable* DeclareVariableName(const AstRawString* name, VariableMode mode);
     202             : 
     203             :   // Declarations list.
     204             :   ThreadedList<Declaration>* declarations() { return &decls_; }
     205             : 
     206             :   ThreadedList<Variable>* locals() { return &locals_; }
     207             : 
     208             :   // Create a new unresolved variable.
     209             :   VariableProxy* NewUnresolved(AstNodeFactory* factory,
     210             :                                const AstRawString* name,
     211             :                                int start_position = kNoSourcePosition,
     212             :                                VariableKind kind = NORMAL_VARIABLE);
     213             : 
     214             :   void AddUnresolved(VariableProxy* proxy);
     215             : 
     216             :   // Remove a unresolved variable. During parsing, an unresolved variable
     217             :   // may have been added optimistically, but then only the variable name
     218             :   // was used (typically for labels). If the variable was not declared, the
     219             :   // addition introduced a new unresolved variable which may end up being
     220             :   // allocated globally as a "ghost" variable. RemoveUnresolved removes
     221             :   // such a variable again if it was added; otherwise this is a no-op.
     222             :   bool RemoveUnresolved(VariableProxy* var);
     223             : 
     224             :   // Creates a new temporary variable in this scope's TemporaryScope.  The
     225             :   // name is only used for printing and cannot be used to find the variable.
     226             :   // In particular, the only way to get hold of the temporary is by keeping the
     227             :   // Variable* around.  The name should not clash with a legitimate variable
     228             :   // names.
     229             :   // TODO(verwaest): Move to DeclarationScope?
     230             :   Variable* NewTemporary(const AstRawString* name);
     231             : 
     232             :   // ---------------------------------------------------------------------------
     233             :   // Illegal redeclaration support.
     234             : 
     235             :   // Check if the scope has conflicting var
     236             :   // declarations, i.e. a var declaration that has been hoisted from a nested
     237             :   // scope over a let binding of the same name.
     238             :   Declaration* CheckConflictingVarDeclarations();
     239             : 
     240             :   // Check if the scope has a conflicting lexical declaration that has a name in
     241             :   // the given list. This is used to catch patterns like
     242             :   // `try{}catch(e){let e;}`,
     243             :   // which is an error even though the two 'e's are declared in different
     244             :   // scopes.
     245             :   Declaration* CheckLexDeclarationsConflictingWith(
     246             :       const ZoneList<const AstRawString*>& names);
     247             : 
     248             :   // ---------------------------------------------------------------------------
     249             :   // Scope-specific info.
     250             : 
     251             :   // Inform the scope and outer scopes that the corresponding code contains an
     252             :   // eval call.
     253     2475186 :   void RecordEvalCall() {
     254     2475186 :     scope_calls_eval_ = true;
     255     2475186 :     inner_scope_calls_eval_ = true;
     256     2012194 :     for (Scope* scope = outer_scope(); scope != nullptr;
     257             :          scope = scope->outer_scope()) {
     258     2012194 :       scope->inner_scope_calls_eval_ = true;
     259             :     }
     260             :   }
     261             : 
     262             :   // Set the language mode flag (unless disabled by a global flag).
     263     9545573 :   void SetLanguageMode(LanguageMode language_mode) {
     264             :     DCHECK(!is_module_scope() || is_strict(language_mode));
     265             :     set_language_mode(language_mode);
     266     9545573 :   }
     267             : 
     268             :   // Inform the scope that the scope may execute declarations nonlinearly.
     269             :   // Currently, the only nonlinear scope is a switch statement. The name is
     270             :   // more general in case something else comes up with similar control flow,
     271             :   // for example the ability to break out of something which does not have
     272             :   // its own lexical scope.
     273             :   // The bit does not need to be stored on the ScopeInfo because none of
     274             :   // the three compilers will perform hole check elimination on a variable
     275             :   // located in VariableLocation::CONTEXT. So, direct eval and closures
     276             :   // will not expose holes.
     277      184539 :   void SetNonlinear() { scope_nonlinear_ = true; }
     278             : 
     279             :   // Position in the source where this scope begins and ends.
     280             :   //
     281             :   // * For the scope of a with statement
     282             :   //     with (obj) stmt
     283             :   //   start position: start position of first token of 'stmt'
     284             :   //   end position: end position of last token of 'stmt'
     285             :   // * For the scope of a block
     286             :   //     { stmts }
     287             :   //   start position: start position of '{'
     288             :   //   end position: end position of '}'
     289             :   // * For the scope of a function literal or decalaration
     290             :   //     function fun(a,b) { stmts }
     291             :   //   start position: start position of '('
     292             :   //   end position: end position of '}'
     293             :   // * For the scope of a catch block
     294             :   //     try { stms } catch(e) { stmts }
     295             :   //   start position: start position of '('
     296             :   //   end position: end position of ')'
     297             :   // * For the scope of a for-statement
     298             :   //     for (let x ...) stmt
     299             :   //   start position: start position of '('
     300             :   //   end position: end position of last token of 'stmt'
     301             :   // * For the scope of a switch statement
     302             :   //     switch (tag) { cases }
     303             :   //   start position: start position of '{'
     304             :   //   end position: end position of '}'
     305             :   int start_position() const { return start_position_; }
     306             :   void set_start_position(int statement_pos) {
     307    21345065 :     start_position_ = statement_pos;
     308             :   }
     309             :   int end_position() const { return end_position_; }
     310       92611 :   void set_end_position(int statement_pos) {
     311    21896231 :     end_position_ = statement_pos;
     312       92611 :   }
     313             : 
     314             :   // Scopes created for desugaring are hidden. I.e. not visible to the debugger.
     315      318315 :   bool is_hidden() const { return is_hidden_; }
     316      923080 :   void set_is_hidden() { is_hidden_ = true; }
     317             : 
     318             :   // In some cases we want to force context allocation for a whole scope.
     319             :   void ForceContextAllocation() {
     320             :     DCHECK(!already_resolved_);
     321      110847 :     force_context_allocation_ = true;
     322             :   }
     323             :   bool has_forced_context_allocation() const {
     324    46226264 :     return force_context_allocation_;
     325             :   }
     326             : 
     327             :   // ---------------------------------------------------------------------------
     328             :   // Predicates.
     329             : 
     330             :   // Specific scope types.
     331             :   bool is_eval_scope() const { return scope_type_ == EVAL_SCOPE; }
     332     3434432 :   bool is_function_scope() const { return scope_type_ == FUNCTION_SCOPE; }
     333             :   bool is_module_scope() const { return scope_type_ == MODULE_SCOPE; }
     334             :   bool is_script_scope() const { return scope_type_ == SCRIPT_SCOPE; }
     335             :   bool is_catch_scope() const { return scope_type_ == CATCH_SCOPE; }
     336             :   bool is_block_scope() const { return scope_type_ == BLOCK_SCOPE; }
     337             :   bool is_with_scope() const { return scope_type_ == WITH_SCOPE; }
     338   590896747 :   bool is_declaration_scope() const { return is_declaration_scope_; }
     339             : 
     340             :   // Information about which scopes calls eval.
     341     4032791 :   bool calls_eval() const { return scope_calls_eval_; }
     342             :   bool calls_sloppy_eval() const {
     343    30548417 :     return scope_calls_eval_ && is_sloppy(language_mode());
     344             :   }
     345       44578 :   bool inner_scope_calls_eval() const { return inner_scope_calls_eval_; }
     346             :   bool IsAsmModule() const;
     347             :   bool IsAsmFunction() const;
     348             :   // Does this scope have the potential to execute declarations non-linearly?
     349     1346227 :   bool is_nonlinear() const { return scope_nonlinear_; }
     350             : 
     351             :   // Whether this needs to be represented by a runtime context.
     352    24254656 :   bool NeedsContext() const {
     353             :     // Catch scopes always have heap slots.
     354             :     DCHECK(!is_catch_scope() || num_heap_slots() > 0);
     355     2198937 :     return num_heap_slots() > 0;
     356             :   }
     357             : 
     358             :   // ---------------------------------------------------------------------------
     359             :   // Accessors.
     360             : 
     361             :   // The type of this scope.
     362             :   ScopeType scope_type() const { return scope_type_; }
     363             : 
     364             :   // The language mode of this scope.
     365   192804104 :   LanguageMode language_mode() const { return is_strict_ ? STRICT : SLOPPY; }
     366             : 
     367             :   // inner_scope() and sibling() together implement the inner scope list of a
     368             :   // scope. Inner scope points to the an inner scope of the function, and
     369             :   // "sibling" points to a next inner scope of the outer scope of this scope.
     370             :   Scope* inner_scope() const { return inner_scope_; }
     371             :   Scope* sibling() const { return sibling_; }
     372             : 
     373             :   // The scope immediately surrounding this scope, or NULL.
     374             :   Scope* outer_scope() const { return outer_scope_; }
     375             : 
     376             :   Variable* catch_variable() const {
     377             :     DCHECK(is_catch_scope());
     378             :     DCHECK_EQ(1, num_var());
     379      382646 :     return static_cast<Variable*>(variables_.Start()->value);
     380             :   }
     381             : 
     382             :   // ---------------------------------------------------------------------------
     383             :   // Variable allocation.
     384             : 
     385             :   // Result of variable allocation.
     386             :   int num_stack_slots() const { return num_stack_slots_; }
     387             :   int num_heap_slots() const { return num_heap_slots_; }
     388             : 
     389             :   int StackLocalCount() const;
     390             :   int ContextLocalCount() const;
     391             : 
     392             :   // Determine if we can parse a function literal in this scope lazily without
     393             :   // caring about the unresolved variables within.
     394             :   bool AllowsLazyParsingWithoutUnresolvedVariables(const Scope* outer) const;
     395             : 
     396             :   // The number of contexts between this and scope; zero if this == scope.
     397             :   int ContextChainLength(Scope* scope) const;
     398             : 
     399             :   // The number of contexts between this and the outermost context that has a
     400             :   // sloppy eval call. One if this->calls_sloppy_eval().
     401             :   int ContextChainLengthUntilOutermostSloppyEval() const;
     402             : 
     403             :   // The maximum number of nested contexts required for this scope and any inner
     404             :   // scopes.
     405             :   int MaxNestedContextChainLength();
     406             : 
     407             :   // Find the first function, script, eval or (declaration) block scope. This is
     408             :   // the scope where var declarations will be hoisted to in the implementation.
     409             :   DeclarationScope* GetDeclarationScope();
     410             : 
     411             :   // Find the first non-block declaration scope. This should be either a script,
     412             :   // function, or eval scope. Same as DeclarationScope(), but skips declaration
     413             :   // "block" scopes. Used for differentiating associated function objects (i.e.,
     414             :   // the scope for which a function prologue allocates a context) or declaring
     415             :   // temporaries.
     416             :   DeclarationScope* GetClosureScope();
     417             :   const DeclarationScope* GetClosureScope() const;
     418             : 
     419             :   // Find the first (non-arrow) function or script scope.  This is where
     420             :   // 'this' is bound, and what determines the function kind.
     421             :   DeclarationScope* GetReceiverScope();
     422             : 
     423             :   // Find the module scope, assuming there is one.
     424             :   ModuleScope* GetModuleScope();
     425             : 
     426             :   // Find the innermost outer scope that needs a context.
     427             :   Scope* GetOuterScopeWithContext();
     428             : 
     429             :   // Analyze() must have been called once to create the ScopeInfo.
     430             :   Handle<ScopeInfo> scope_info() const {
     431             :     DCHECK(!scope_info_.is_null());
     432             :     return scope_info_;
     433             :   }
     434             : 
     435             :   // ---------------------------------------------------------------------------
     436             :   // Strict mode support.
     437             :   bool IsDeclared(const AstRawString* name) {
     438             :     // During formal parameter list parsing the scope only contains
     439             :     // two variables inserted at initialization: "this" and "arguments".
     440             :     // "this" is an invalid parameter name and "arguments" is invalid parameter
     441             :     // name in strict mode. Therefore looking up with the map which includes
     442             :     // "this" and "arguments" in addition to all formal parameters is safe.
     443             :     return variables_.Lookup(name) != NULL;
     444             :   }
     445             : 
     446    14340256 :   int num_var() const { return variables_.occupancy(); }
     447             : 
     448             :   // ---------------------------------------------------------------------------
     449             :   // Debugging.
     450             : 
     451             : #ifdef DEBUG
     452             :   void Print(int n = 0);  // n = indentation; n < 0 => don't print recursively
     453             : 
     454             :   // Check that the scope has positions assigned.
     455             :   void CheckScopePositions();
     456             : 
     457             :   // Check that all Scopes in the scope tree use the same Zone.
     458             :   void CheckZones();
     459             : #endif
     460             : 
     461             :   // Retrieve `IsSimpleParameterList` of current or outer function.
     462             :   bool HasSimpleParameters();
     463       33092 :   void set_is_debug_evaluate_scope() { is_debug_evaluate_scope_ = true; }
     464     4032791 :   bool is_debug_evaluate_scope() const { return is_debug_evaluate_scope_; }
     465             : 
     466             :   bool RemoveInnerScope(Scope* inner_scope) {
     467             :     DCHECK_NOT_NULL(inner_scope);
     468    10498951 :     if (inner_scope == inner_scope_) {
     469    10432248 :       inner_scope_ = inner_scope_->sibling_;
     470             :       return true;
     471             :     }
     472      135118 :     for (Scope* scope = inner_scope_; scope != nullptr;
     473             :          scope = scope->sibling_) {
     474      135118 :       if (scope->sibling_ == inner_scope) {
     475       66703 :         scope->sibling_ = scope->sibling_->sibling_;
     476             :         return true;
     477             :       }
     478             :     }
     479             :     return false;
     480             :   }
     481             : 
     482             :  protected:
     483             :   explicit Scope(Zone* zone);
     484             : 
     485             :   void set_language_mode(LanguageMode language_mode) {
     486   108420937 :     is_strict_ = is_strict(language_mode);
     487             :   }
     488             : 
     489             :  private:
     490             :   Variable* Declare(
     491             :       Zone* zone, const AstRawString* name, VariableMode mode,
     492             :       VariableKind kind = NORMAL_VARIABLE,
     493             :       InitializationFlag initialization_flag = kCreatedInitialized,
     494             :       MaybeAssignedFlag maybe_assigned_flag = kNotAssigned);
     495             : 
     496             :   // This method should only be invoked on scopes created during parsing (i.e.,
     497             :   // not deserialized from a context). Also, since NeedsContext() is only
     498             :   // returning a valid result after variables are resolved, NeedsScopeInfo()
     499             :   // should also be invoked after resolution.
     500             :   bool NeedsScopeInfo() const;
     501             : 
     502             :   Variable* NewTemporary(const AstRawString* name,
     503             :                          MaybeAssignedFlag maybe_assigned);
     504             :   Zone* zone_;
     505             : 
     506             :   // Scope tree.
     507             :   Scope* outer_scope_;  // the immediately enclosing outer scope, or NULL
     508             :   Scope* inner_scope_;  // an inner scope of this scope
     509             :   Scope* sibling_;  // a sibling inner scope of the outer scope of this scope.
     510             : 
     511             :   // The variables declared in this scope:
     512             :   //
     513             :   // All user-declared variables (incl. parameters).  For script scopes
     514             :   // variables may be implicitly 'declared' by being used (possibly in
     515             :   // an inner scope) with no intervening with statements or eval calls.
     516             :   VariableMap variables_;
     517             :   // In case of non-scopeinfo-backed scopes, this contains the variables of the
     518             :   // map above in order of addition.
     519             :   ThreadedList<Variable> locals_;
     520             :   // Unresolved variables referred to from this scope. The proxies themselves
     521             :   // form a linked list of all unresolved proxies.
     522             :   VariableProxy* unresolved_;
     523             :   // Declarations.
     524             :   ThreadedList<Declaration> decls_;
     525             : 
     526             :   // Serialized scope info support.
     527             :   Handle<ScopeInfo> scope_info_;
     528             : // Debugging support.
     529             : #ifdef DEBUG
     530             :   const AstRawString* scope_name_;
     531             : 
     532             :   // True if it doesn't need scope resolution (e.g., if the scope was
     533             :   // constructed based on a serialized scope info or a catch context).
     534             :   bool already_resolved_;
     535             :   // True if this scope may contain objects from a temp zone that needs to be
     536             :   // fixed up.
     537             :   bool needs_migration_;
     538             : #endif
     539             : 
     540             :   // Source positions.
     541             :   int start_position_;
     542             :   int end_position_;
     543             : 
     544             :   // Computed via AllocateVariables.
     545             :   int num_stack_slots_;
     546             :   int num_heap_slots_;
     547             : 
     548             :   // The scope type.
     549             :   const ScopeType scope_type_;
     550             : 
     551             :   // Scope-specific information computed during parsing.
     552             :   //
     553             :   // The language mode of this scope.
     554             :   STATIC_ASSERT(LANGUAGE_END == 2);
     555             :   bool is_strict_ : 1;
     556             :   // This scope or a nested catch scope or with scope contain an 'eval' call. At
     557             :   // the 'eval' call site this scope is the declaration scope.
     558             :   bool scope_calls_eval_ : 1;
     559             :   // This scope's declarations might not be executed in order (e.g., switch).
     560             :   bool scope_nonlinear_ : 1;
     561             :   bool is_hidden_ : 1;
     562             :   // Temporary workaround that allows masking of 'this' in debug-evalute scopes.
     563             :   bool is_debug_evaluate_scope_ : 1;
     564             : 
     565             :   // True if one of the inner scopes or the scope itself calls eval.
     566             :   bool inner_scope_calls_eval_ : 1;
     567             :   bool force_context_allocation_ : 1;
     568             : 
     569             :   // True if it holds 'var' declarations.
     570             :   bool is_declaration_scope_ : 1;
     571             : 
     572             :   bool must_use_preparsed_scope_data_ : 1;
     573             : 
     574             :   // Create a non-local variable with a given name.
     575             :   // These variables are looked up dynamically at runtime.
     576             :   Variable* NonLocal(const AstRawString* name, VariableMode mode);
     577             : 
     578             :   // Variable resolution.
     579             :   // Lookup a variable reference given by name recursively starting with this
     580             :   // scope, and stopping when reaching the outer_scope_end scope. If the code is
     581             :   // executed because of a call to 'eval', the context parameter should be set
     582             :   // to the calling context of 'eval'.
     583             :   Variable* LookupRecursive(VariableProxy* proxy, Scope* outer_scope_end);
     584             :   void ResolveTo(ParseInfo* info, VariableProxy* proxy, Variable* var);
     585             :   void ResolveVariable(ParseInfo* info, VariableProxy* proxy);
     586             :   void ResolveVariablesRecursively(ParseInfo* info);
     587             : 
     588             :   // Finds free variables of this scope. This mutates the unresolved variables
     589             :   // list along the way, so full resolution cannot be done afterwards.
     590             :   // If a ParseInfo* is passed, non-free variables will be resolved.
     591             :   VariableProxy* FetchFreeVariables(DeclarationScope* max_outer_scope,
     592             :                                     ParseInfo* info = nullptr,
     593             :                                     VariableProxy* stack = nullptr);
     594             : 
     595             :   // Predicates.
     596             :   bool MustAllocate(Variable* var);
     597             :   bool MustAllocateInContext(Variable* var);
     598             : 
     599             :   // Variable allocation.
     600             :   void AllocateStackSlot(Variable* var);
     601             :   void AllocateHeapSlot(Variable* var);
     602             :   void AllocateNonParameterLocal(Variable* var);
     603             :   void AllocateDeclaredGlobal(Variable* var);
     604             :   void AllocateNonParameterLocalsAndDeclaredGlobals();
     605             :   void AllocateVariablesRecursively();
     606             : 
     607             :   void AllocateScopeInfosRecursively(Isolate* isolate,
     608             :                                      MaybeHandle<ScopeInfo> outer_scope);
     609             :   void AllocateDebuggerScopeInfos(Isolate* isolate,
     610             :                                   MaybeHandle<ScopeInfo> outer_scope);
     611             : 
     612             :   // Construct a scope based on the scope info.
     613             :   Scope(Zone* zone, ScopeType type, Handle<ScopeInfo> scope_info);
     614             : 
     615             :   // Construct a catch scope with a binding for the name.
     616             :   Scope(Zone* zone, const AstRawString* catch_variable_name,
     617             :         MaybeAssignedFlag maybe_assigned, Handle<ScopeInfo> scope_info);
     618             : 
     619             :   void AddInnerScope(Scope* inner_scope) {
     620    26032879 :     inner_scope->sibling_ = inner_scope_;
     621    26032879 :     inner_scope_ = inner_scope;
     622     5040552 :     inner_scope->outer_scope_ = this;
     623             :   }
     624             : 
     625             :   void SetDefaults();
     626             : 
     627             :   friend class DeclarationScope;
     628             :   friend class ScopeTestHelper;
     629             : };
     630             : 
     631             : class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
     632             :  public:
     633             :   DeclarationScope(Zone* zone, Scope* outer_scope, ScopeType scope_type,
     634             :                    FunctionKind function_kind = kNormalFunction);
     635             :   DeclarationScope(Zone* zone, ScopeType scope_type,
     636             :                    Handle<ScopeInfo> scope_info);
     637             :   // Creates a script scope.
     638             :   DeclarationScope(Zone* zone, AstValueFactory* ast_value_factory);
     639             : 
     640     8895151 :   bool IsDeclaredParameter(const AstRawString* name) {
     641             :     // If IsSimpleParameterList is false, duplicate parameters are not allowed,
     642             :     // however `arguments` may be allowed if function is not strict code. Thus,
     643             :     // the assumptions explained above do not hold.
     644    17790302 :     return params_.Contains(variables_.Lookup(name));
     645             :   }
     646             : 
     647             :   FunctionKind function_kind() const { return function_kind_; }
     648             : 
     649             :   bool is_arrow_scope() const {
     650    17881240 :     return is_function_scope() && IsArrowFunction(function_kind_);
     651             :   }
     652             : 
     653             :   // Inform the scope that the corresponding code uses "super".
     654        7852 :   void RecordSuperPropertyUsage() { scope_uses_super_property_ = true; }
     655             :   // Does this scope access "super" property (super.foo).
     656       25661 :   bool uses_super_property() const { return scope_uses_super_property_; }
     657             : 
     658     8461534 :   bool NeedsHomeObject() const {
     659     8093679 :     return scope_uses_super_property_ ||
     660      724855 :            (inner_scope_calls_eval_ && (IsConciseMethod(function_kind()) ||
     661      348456 :                                         IsAccessorFunction(function_kind()) ||
     662     8093679 :                                         IsClassConstructor(function_kind())));
     663             :   }
     664             : 
     665    20049133 :   bool was_lazily_parsed() const { return was_lazily_parsed_; }
     666             : 
     667             : #ifdef DEBUG
     668             :   void set_is_being_lazily_parsed(bool is_being_lazily_parsed) {
     669             :     is_being_lazily_parsed_ = is_being_lazily_parsed;
     670             :   }
     671             :   bool is_being_lazily_parsed() const { return is_being_lazily_parsed_; }
     672             : #endif
     673             : 
     674             :   bool ShouldEagerCompile() const;
     675             :   void set_should_eager_compile();
     676             : 
     677             :   void SetScriptScopeInfo(Handle<ScopeInfo> scope_info) {
     678             :     DCHECK(is_script_scope());
     679             :     DCHECK(scope_info_.is_null());
     680      259240 :     scope_info_ = scope_info;
     681             :   }
     682             : 
     683    16596253 :   bool asm_module() const { return asm_module_; }
     684             :   void set_asm_module();
     685     8349759 :   bool asm_function() const { return asm_function_; }
     686          18 :   void set_asm_function() { asm_function_ = true; }
     687             : 
     688             :   void DeclareThis(AstValueFactory* ast_value_factory);
     689             :   void DeclareArguments(AstValueFactory* ast_value_factory);
     690             :   void DeclareDefaultFunctionVariables(AstValueFactory* ast_value_factory);
     691             : 
     692             :   // Declare the function variable for a function literal. This variable
     693             :   // is in an intermediate scope between this function scope and the the
     694             :   // outer scope. Only possible for function scopes; at most one variable.
     695             :   //
     696             :   // This function needs to be called after all other variables have been
     697             :   // declared in the scope. It will add a variable for {name} to {variables_};
     698             :   // either the function variable itself, or a non-local in case the function
     699             :   // calls sloppy eval.
     700             :   Variable* DeclareFunctionVar(const AstRawString* name);
     701             : 
     702             :   // Declare some special internal variables which must be accessible to
     703             :   // Ignition without ScopeInfo.
     704             :   Variable* DeclareGeneratorObjectVar(const AstRawString* name);
     705             :   Variable* DeclarePromiseVar(const AstRawString* name);
     706             :   Variable* DeclareAsyncGeneratorAwaitVar(const AstRawString* name);
     707             : 
     708             :   // Declare a parameter in this scope.  When there are duplicated
     709             :   // parameters the rightmost one 'wins'.  However, the implementation
     710             :   // expects all parameters to be declared and from left to right.
     711             :   Variable* DeclareParameter(const AstRawString* name, VariableMode mode,
     712             :                              bool is_optional, bool is_rest, bool* is_duplicate,
     713             :                              AstValueFactory* ast_value_factory, int position);
     714             : 
     715             :   // Declares that a parameter with the name exists. Creates a Variable and
     716             :   // returns it if FLAG_preparser_scope_analysis is on.
     717             :   Variable* DeclareParameterName(const AstRawString* name, bool is_rest,
     718             :                                  AstValueFactory* ast_value_factory);
     719             : 
     720             :   // Declare an implicit global variable in this scope which must be a
     721             :   // script scope.  The variable was introduced (possibly from an inner
     722             :   // scope) by a reference to an unresolved variable with no intervening
     723             :   // with statements or eval calls.
     724             :   Variable* DeclareDynamicGlobal(const AstRawString* name,
     725             :                                  VariableKind variable_kind);
     726             : 
     727             :   // The variable corresponding to the 'this' value.
     728             :   Variable* receiver() {
     729             :     DCHECK(has_this_declaration());
     730             :     DCHECK_NOT_NULL(receiver_);
     731             :     return receiver_;
     732             :   }
     733             : 
     734             :   // TODO(wingo): Add a GLOBAL_SCOPE scope type which will lexically allocate
     735             :   // "this" (and no other variable) on the native context.  Script scopes then
     736             :   // will not have a "this" declaration.
     737             :   bool has_this_declaration() const {
     738    20936459 :     return (is_function_scope() && !is_arrow_scope()) || is_module_scope();
     739             :   }
     740             : 
     741             :   // The variable corresponding to the 'new.target' value.
     742             :   Variable* new_target_var() { return new_target_; }
     743             : 
     744             :   // The variable holding the function literal for named function
     745             :   // literals, or NULL.  Only valid for function scopes.
     746             :   Variable* function_var() const {
     747             :     DCHECK(is_function_scope());
     748             :     return function_;
     749             :   }
     750             : 
     751      388614 :   Variable* generator_object_var() const {
     752             :     DCHECK(is_function_scope() || is_module_scope());
     753             :     return GetRareVariable(RareVariable::kGeneratorObject);
     754             :   }
     755             : 
     756      671920 :   Variable* promise_var() const {
     757             :     DCHECK(is_function_scope());
     758             :     DCHECK(IsAsyncFunction(function_kind_));
     759     1343840 :     if (IsAsyncGeneratorFunction(function_kind_)) return nullptr;
     760             :     return GetRareVariable(RareVariable::kPromise);
     761             :   }
     762             : 
     763       32860 :   Variable* async_generator_await_var() const {
     764             :     DCHECK(is_function_scope());
     765             :     DCHECK(IsAsyncGeneratorFunction(function_kind_));
     766             :     return GetRareVariable(RareVariable::kAsyncGeneratorAwaitResult);
     767             :   }
     768             : 
     769             :   // Parameters. The left-most parameter has index 0.
     770             :   // Only valid for function and module scopes.
     771             :   Variable* parameter(int index) const {
     772             :     DCHECK(is_function_scope() || is_module_scope());
     773     8409632 :     return params_[index];
     774             :   }
     775             : 
     776             :   // Returns the number of formal parameters, excluding a possible rest
     777             :   // parameter.  Examples:
     778             :   //   function foo(a, b) {}         ==> 2
     779             :   //   function foo(a, b, ...c) {}   ==> 2
     780             :   //   function foo(a, b, c = 1) {}  ==> 3
     781             :   int num_parameters() const {
     782    17242355 :     return has_rest_ ? params_.length() - 1 : params_.length();
     783             :   }
     784             : 
     785             :   // The function's rest parameter (nullptr if there is none).
     786             :   Variable* rest_parameter() const {
     787     5949704 :     return has_rest_ ? params_[params_.length() - 1] : nullptr;
     788             :   }
     789             : 
     790     2585153 :   bool has_simple_parameters() const { return has_simple_parameters_; }
     791             : 
     792             :   // TODO(caitp): manage this state in a better way. PreParser must be able to
     793             :   // communicate that the scope is non-simple, without allocating any parameters
     794             :   // as the Parser does. This is necessary to ensure that TC39's proposed early
     795             :   // error can be reported consistently regardless of whether lazily parsed or
     796             :   // not.
     797       91127 :   void SetHasNonSimpleParameters() {
     798             :     DCHECK(is_function_scope());
     799      122227 :     has_simple_parameters_ = false;
     800       91127 :   }
     801             : 
     802             :   // The local variable 'arguments' if we need to allocate it; NULL otherwise.
     803             :   Variable* arguments() const {
     804             :     DCHECK(!is_arrow_scope() || arguments_ == nullptr);
     805             :     return arguments_;
     806             :   }
     807             : 
     808     5781896 :   Variable* this_function_var() const {
     809             :     Variable* this_function = GetRareVariable(RareVariable::kThisFunction);
     810             : 
     811             :     // This is only used in derived constructors atm.
     812             :     DCHECK(this_function == nullptr ||
     813             :            (is_function_scope() && (IsClassConstructor(function_kind()) ||
     814             :                                     IsConciseMethod(function_kind()) ||
     815             :                                     IsAccessorFunction(function_kind()))));
     816             :     return this_function;
     817             :   }
     818             : 
     819             :   // Adds a local variable in this scope's locals list. This is for adjusting
     820             :   // the scope of temporaries and do-expression vars when desugaring parameter
     821             :   // initializers.
     822             :   void AddLocal(Variable* var);
     823             : 
     824             :   void DeclareSloppyBlockFunction(
     825             :       const AstRawString* name, Scope* scope,
     826             :       SloppyBlockFunctionStatement* statement = nullptr);
     827             : 
     828             :   // Go through sloppy_block_function_map_ and hoist those (into this scope)
     829             :   // which should be hoisted.
     830             :   void HoistSloppyBlockFunctions(AstNodeFactory* factory);
     831             : 
     832             :   SloppyBlockFunctionMap* sloppy_block_function_map() {
     833             :     return sloppy_block_function_map_;
     834             :   }
     835             : 
     836             :   // Compute top scope and allocate variables. For lazy compilation the top
     837             :   // scope only contains the single lazily compiled function, so this
     838             :   // doesn't re-allocate variables repeatedly.
     839             :   static void Analyze(ParseInfo* info, Isolate* isolate, AnalyzeMode mode);
     840             : 
     841             :   // To be called during parsing. Do just enough scope analysis that we can
     842             :   // discard the Scope for lazily compiled functions. In particular, this
     843             :   // records variables which cannot be resolved inside the Scope (we don't yet
     844             :   // know what they will resolve to since the outer Scopes are incomplete) and
     845             :   // migrates them into migrate_to.
     846             :   void AnalyzePartially(AstNodeFactory* ast_node_factory,
     847             :                         PreParsedScopeData* preparsed_scope_data);
     848             : 
     849             :   Handle<StringSet> CollectNonLocals(ParseInfo* info,
     850             :                                      Handle<StringSet> non_locals);
     851             : 
     852             :   // Determine if we can use lazy compilation for this scope.
     853             :   bool AllowsLazyCompilation() const;
     854             : 
     855             :   // Make sure this closure and all outer closures are eagerly compiled.
     856        2994 :   void ForceEagerCompilation() {
     857             :     DCHECK_EQ(this, GetClosureScope());
     858             :     DeclarationScope* s;
     859        6000 :     for (s = this; !s->is_script_scope();
     860        3006 :          s = s->outer_scope()->GetClosureScope()) {
     861           6 :       s->force_eager_compilation_ = true;
     862             :     }
     863        2994 :     s->force_eager_compilation_ = true;
     864        2994 :   }
     865             : 
     866             : #ifdef DEBUG
     867             :   void PrintParameters();
     868             : #endif
     869             : 
     870             :   void AllocateLocals();
     871             :   void AllocateParameterLocals();
     872             :   void AllocateReceiver();
     873             : 
     874             :   void ResetAfterPreparsing(AstValueFactory* ast_value_factory, bool aborted);
     875             : 
     876       32025 :   bool is_skipped_function() const { return is_skipped_function_; }
     877             :   void set_is_skipped_function(bool is_skipped_function) {
     878          14 :     is_skipped_function_ = is_skipped_function;
     879             :   }
     880             : 
     881             :  private:
     882             :   void AllocateParameter(Variable* var, int index);
     883             : 
     884             :   // Resolve and fill in the allocation information for all variables
     885             :   // in this scopes. Must be called *after* all scopes have been
     886             :   // processed (parsed) to ensure that unresolved variables can be
     887             :   // resolved properly.
     888             :   //
     889             :   // In the case of code compiled and run using 'eval', the context
     890             :   // parameter is the context in which eval was called.  In all other
     891             :   // cases the context parameter is an empty handle.
     892             :   void AllocateVariables(ParseInfo* info, Isolate* isolate, AnalyzeMode mode);
     893             : 
     894             :   void SetDefaults();
     895             : 
     896             :   // If the scope is a function scope, this is the function kind.
     897             :   const FunctionKind function_kind_;
     898             : 
     899             :   bool has_simple_parameters_ : 1;
     900             :   // This scope contains an "use asm" annotation.
     901             :   bool asm_module_ : 1;
     902             :   // This scope's outer context is an asm module.
     903             :   bool asm_function_ : 1;
     904             :   bool force_eager_compilation_ : 1;
     905             :   // This function scope has a rest parameter.
     906             :   bool has_rest_ : 1;
     907             :   // This scope has a parameter called "arguments".
     908             :   bool has_arguments_parameter_ : 1;
     909             :   // This scope uses "super" property ('super.foo').
     910             :   bool scope_uses_super_property_ : 1;
     911             :   bool should_eager_compile_ : 1;
     912             :   // Set to true after we have finished lazy parsing the scope.
     913             :   bool was_lazily_parsed_ : 1;
     914             : #if DEBUG
     915             :   bool is_being_lazily_parsed_ : 1;
     916             : #endif
     917             :   bool is_skipped_function_ : 1;
     918             : 
     919             :   // Parameter list in source order.
     920             :   ZoneList<Variable*> params_;
     921             :   // Map of function names to lists of functions defined in sloppy blocks
     922             :   SloppyBlockFunctionMap* sloppy_block_function_map_;
     923             :   // Convenience variable.
     924             :   Variable* receiver_;
     925             :   // Function variable, if any; function scopes only.
     926             :   Variable* function_;
     927             :   // new.target variable, function scopes only.
     928             :   Variable* new_target_;
     929             :   // Convenience variable; function scopes only.
     930             :   Variable* arguments_;
     931             : 
     932      775639 :   struct RareData : public ZoneObject {
     933             :     // Convenience variable; Subclass constructor only
     934             :     Variable* this_function = nullptr;
     935             : 
     936             :     // Generator object, if any; generator function scopes and module scopes
     937             :     // only.
     938             :     Variable* generator_object = nullptr;
     939             :     // Promise, if any; async function scopes only.
     940             :     Variable* promise = nullptr;
     941             :   };
     942             : 
     943             :   enum class RareVariable {
     944             :     kThisFunction = offsetof(RareData, this_function),
     945             :     kGeneratorObject = offsetof(RareData, generator_object),
     946             :     kPromise = offsetof(RareData, promise),
     947             :     kAsyncGeneratorAwaitResult = kPromise
     948             :   };
     949             : 
     950             :   V8_INLINE RareData* EnsureRareData() {
     951      832625 :     if (rare_data_ == nullptr) {
     952      775639 :       rare_data_ = new (zone_) RareData;
     953             :     }
     954      832625 :     return rare_data_;
     955             :   }
     956             : 
     957             :   V8_INLINE Variable* GetRareVariable(RareVariable id) const {
     958     6875290 :     if (rare_data_ == nullptr) return nullptr;
     959             :     return *reinterpret_cast<Variable**>(
     960     1305403 :         reinterpret_cast<uint8_t*>(rare_data_) + static_cast<ptrdiff_t>(id));
     961             :   }
     962             : 
     963             :   // Set `var` to null if it's non-null and Predicate (Variable*) -> bool
     964             :   // returns true.
     965             :   template <typename Predicate>
     966             :   V8_INLINE void NullifyRareVariableIf(RareVariable id, Predicate predicate) {
     967     8132147 :     if (V8_LIKELY(rare_data_ == nullptr)) return;
     968             :     Variable** var = reinterpret_cast<Variable**>(
     969             :         reinterpret_cast<uint8_t*>(rare_data_) + static_cast<ptrdiff_t>(id));
     970      504512 :     if (*var && predicate(*var)) *var = nullptr;
     971             :   }
     972             : 
     973             :   RareData* rare_data_ = nullptr;
     974             : };
     975             : 
     976             : class ModuleScope final : public DeclarationScope {
     977             :  public:
     978             :   ModuleScope(DeclarationScope* script_scope,
     979             :               AstValueFactory* ast_value_factory);
     980             : 
     981             :   // Deserialization.
     982             :   // The generated ModuleDescriptor does not preserve all information.  In
     983             :   // particular, its module_requests map will be empty because we no longer need
     984             :   // the map after parsing.
     985             :   ModuleScope(Handle<ScopeInfo> scope_info, AstValueFactory* ast_value_factory);
     986             : 
     987             :   ModuleDescriptor* module() const {
     988             :     DCHECK_NOT_NULL(module_descriptor_);
     989             :     return module_descriptor_;
     990             :   }
     991             : 
     992             :   // Set MODULE as VariableLocation for all variables that will live in a
     993             :   // module's export table.
     994             :   void AllocateModuleVariables();
     995             : 
     996             :  private:
     997             :   ModuleDescriptor* module_descriptor_;
     998             : };
     999             : 
    1000             : }  // namespace internal
    1001             : }  // namespace v8
    1002             : 
    1003             : #endif  // V8_AST_SCOPES_H_

Generated by: LCOV version 1.10