LCOV - code coverage report
Current view: top level - src/ast - scopes.h (source / functions) Hit Total Coverage
Test: app.info Lines: 98 98 100.0 %
Date: 2017-10-20 Functions: 12 12 100.0 %

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

Generated by: LCOV version 1.10