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