Chromium Code Reviews| Index: src/ast/scopes.h |
| diff --git a/src/ast/scopes.h b/src/ast/scopes.h |
| index b60d3b188e1f93cd6e68c226762c45496fb41ff8..07c880543c171305b6293329d0fd6121618790fd 100644 |
| --- a/src/ast/scopes.h |
| +++ b/src/ast/scopes.h |
| @@ -84,23 +84,38 @@ class SloppyBlockFunctionMap : public ZoneHashMap { |
| // a location. Note that many VariableProxy nodes may refer to the same Java- |
| // Script variable. |
| +class DeclarationScope; |
| + |
| +// JS environments are represented in the parser using two scope classes, Scope |
| +// and its subclass DeclarationScope. DeclarationScope is used for any scope |
| +// that hosts 'var' declarations. This includes script, module, eval, varblock, |
| +// and function scope. All fields required by such scopes are only available on |
| +// DeclarationScope. |
| class Scope: public ZoneObject { |
| public: |
| // --------------------------------------------------------------------------- |
| // Construction |
| - Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type, |
| - FunctionKind function_kind = kNormalFunction); |
| + Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type); |
| + |
| +#ifdef DEBUG |
| + // The scope name is only used for printing/debugging. |
| + void SetScopeName(const AstRawString* scope_name) { |
| + scope_name_ = scope_name; |
| + } |
| +#endif |
| + |
| + // TODO(verwaest): Is this needed on Scope? |
| + int num_parameters() const; |
| + |
| + DeclarationScope* AsDeclarationScope(); |
| + const DeclarationScope* AsDeclarationScope() const; |
| class Snapshot final BASE_EMBEDDED { |
| public: |
| - explicit Snapshot(Scope* scope) |
| - : outer_scope_(scope), |
| - top_inner_scope_(scope->inner_scope_), |
| - top_unresolved_(scope->unresolved_), |
| - top_temp_(scope->ClosureScope()->temps_.length()) {} |
| + explicit Snapshot(Scope* scope); |
| - void Reparent(Scope* new_parent) const; |
| + void Reparent(DeclarationScope* new_parent) const; |
| private: |
| Scope* outer_scope_; |
| @@ -117,20 +132,11 @@ class Scope: public ZoneObject { |
| enum class DeserializationMode { kDeserializeOffHeap, kKeepScopeInfo }; |
| static Scope* DeserializeScopeChain(Isolate* isolate, Zone* zone, |
| - Context* context, Scope* script_scope, |
| + Context* context, |
| + DeclarationScope* script_scope, |
| AstValueFactory* ast_value_factory, |
| DeserializationMode deserialization_mode); |
| -#ifdef DEBUG |
| - // The scope name is only used for printing/debugging. |
| - void SetScopeName(const AstRawString* scope_name) { |
| - scope_name_ = scope_name; |
| - } |
| -#endif |
| - |
| - void DeclareThis(AstValueFactory* ast_value_factory); |
| - void DeclareDefaultFunctionVariables(AstValueFactory* ast_value_factory); |
| - |
| // Checks if the block scope is redundant, i.e. it does not contain any |
| // block scoped declarations. In that case it is removed from the scope |
| // tree and its children are reparented. |
| @@ -153,46 +159,18 @@ class Scope: public ZoneObject { |
| // Lookup a variable in this scope. Returns the variable or NULL if not found. |
| Variable* LookupLocal(const AstRawString* name); |
| - // This lookup corresponds to a lookup in the "intermediate" scope sitting |
| - // between this scope and the outer scope. (ECMA-262, 3rd., requires that |
| - // the name of named function literal is kept in an intermediate scope |
| - // in between this scope and the next outer scope.) |
| - Variable* LookupFunctionVar(const AstRawString* name, |
| - AstNodeFactory* factory); |
| - |
| // Lookup a variable in this scope or outer scopes. |
| // Returns the variable or NULL if not found. |
| Variable* Lookup(const AstRawString* name); |
| - // Declare the function variable for a function literal. This variable |
| - // is in an intermediate scope between this function scope and the the |
| - // outer scope. Only possible for function scopes; at most one variable. |
| - void DeclareFunctionVar(VariableDeclaration* declaration) { |
| - DCHECK(is_function_scope()); |
| - // Handle implicit declaration of the function name in named function |
| - // expressions before other declarations. |
| - decls_.InsertAt(0, declaration, zone()); |
| - function_ = declaration; |
| - } |
| - |
| - // Declare a parameter in this scope. When there are duplicated |
| - // parameters the rightmost one 'wins'. However, the implementation |
| - // expects all parameters to be declared and from left to right. |
| - Variable* DeclareParameter(const AstRawString* name, VariableMode mode, |
| - bool is_optional, bool is_rest, bool* is_duplicate, |
| - AstValueFactory* ast_value_factory); |
| - |
| // Declare a local variable in this scope. If the variable has been |
| // declared before, the previously declared variable is returned. |
| Variable* DeclareLocal(const AstRawString* name, VariableMode mode, |
| InitializationFlag init_flag, Variable::Kind kind, |
| MaybeAssignedFlag maybe_assigned_flag = kNotAssigned); |
| - // Declare an implicit global variable in this scope which must be a |
| - // script scope. The variable was introduced (possibly from an inner |
| - // scope) by a reference to an unresolved variable with no intervening |
| - // with statements or eval calls. |
| - Variable* DeclareDynamicGlobal(const AstRawString* name); |
| + // Declarations list. |
| + ZoneList<Declaration*>* declarations() { return &decls_; } |
| // Create a new unresolved variable. |
| VariableProxy* NewUnresolved(AstNodeFactory* factory, |
| @@ -232,23 +210,9 @@ class Scope: public ZoneObject { |
| // In particular, the only way to get hold of the temporary is by keeping the |
| // Variable* around. The name should not clash with a legitimate variable |
| // names. |
| + // TODO(verwaest): Move to DeclarationScope? |
| Variable* NewTemporary(const AstRawString* name); |
| - // Remove a temporary variable. This is for adjusting the scope of |
| - // temporaries used when desugaring parameter initializers. |
| - // Returns the index at which it was found in this scope, or -1 if |
| - // it was not found. |
| - int RemoveTemporary(Variable* var); |
| - |
| - // Adds a temporary variable in this scope's TemporaryScope. This is for |
| - // adjusting the scope of temporaries used when desugaring parameter |
| - // initializers. |
| - void AddTemporary(Variable* var) { |
| - // Temporaries are only placed in ClosureScopes. |
| - DCHECK_EQ(ClosureScope(), this); |
| - temps_.Add(var, zone()); |
| - } |
| - |
| // Adds the specific declaration node to the list of declarations in |
| // this scope. The declarations are processed as part of entering |
| // the scope; see codegen.cc:ProcessDeclarations. |
| @@ -358,13 +322,8 @@ class Scope: public ZoneObject { |
| bool is_catch_scope() const { return scope_type_ == CATCH_SCOPE; } |
| bool is_block_scope() const { return scope_type_ == BLOCK_SCOPE; } |
| bool is_with_scope() const { return scope_type_ == WITH_SCOPE; } |
| - bool is_arrow_scope() const { |
| - return is_function_scope() && IsArrowFunction(function_kind_); |
| - } |
| bool is_declaration_scope() const { return is_declaration_scope_; } |
| - void set_is_declaration_scope() { is_declaration_scope_ = true; } |
| - |
| // Information about which scopes calls eval. |
| bool calls_eval() const { return scope_calls_eval_; } |
| bool calls_sloppy_eval() const { |
| @@ -392,125 +351,15 @@ class Scope: public ZoneObject { |
| return is_with_scope() || num_heap_slots() > 0; |
| } |
| - bool NeedsHomeObject() const { |
| - return scope_uses_super_property_ || |
| - ((scope_calls_eval_ || inner_scope_calls_eval_) && |
| - (IsConciseMethod(function_kind()) || |
| - IsAccessorFunction(function_kind()) || |
| - IsClassConstructor(function_kind()))); |
| - } |
| - |
| // --------------------------------------------------------------------------- |
| // Accessors. |
| // The type of this scope. |
| ScopeType scope_type() const { return scope_type_; } |
| - FunctionKind function_kind() const { return function_kind_; } |
| - |
| // The language mode of this scope. |
| LanguageMode language_mode() const { return language_mode_; } |
| - // The variable corresponding to the 'this' value. |
| - Variable* receiver() { |
| - DCHECK(has_this_declaration()); |
| - DCHECK_NOT_NULL(receiver_); |
| - return receiver_; |
| - } |
| - |
| - // TODO(wingo): Add a GLOBAL_SCOPE scope type which will lexically allocate |
| - // "this" (and no other variable) on the native context. Script scopes then |
| - // will not have a "this" declaration. |
| - bool has_this_declaration() const { |
| - return (is_function_scope() && !is_arrow_scope()) || is_module_scope(); |
| - } |
| - |
| - // The variable corresponding to the 'new.target' value. |
| - Variable* new_target_var() { return new_target_; } |
| - |
| - // The variable holding the function literal for named function |
| - // literals, or NULL. Only valid for function scopes. |
| - VariableDeclaration* function() const { |
| - DCHECK(is_function_scope()); |
| - return function_; |
| - } |
| - |
| - // Parameters. The left-most parameter has index 0. |
| - // Only valid for function scopes. |
| - Variable* parameter(int index) const { |
| - DCHECK(is_function_scope()); |
| - return params_[index]; |
| - } |
| - |
| - // Returns the default function arity excluding default or rest parameters. |
| - int default_function_length() const { return arity_; } |
| - |
| - // Returns the number of formal parameters, up to but not including the |
| - // rest parameter index (if the function has rest parameters), i.e. it |
| - // says 2 for |
| - // |
| - // function foo(a, b) { ... } |
| - // |
| - // and |
| - // |
| - // function foo(a, b, ...c) { ... } |
| - // |
| - // but for |
| - // |
| - // function foo(a, b, c = 1) { ... } |
| - // |
| - // we return 3 here. |
| - int num_parameters() const { |
| - return has_rest_parameter() ? params_.length() - 1 : params_.length(); |
| - } |
| - |
| - // A function can have at most one rest parameter. Returns Variable* or NULL. |
| - Variable* rest_parameter(int* index) const { |
| - *index = rest_index_; |
| - if (rest_index_ < 0) return NULL; |
| - return rest_parameter_; |
| - } |
| - |
| - bool has_rest_parameter() const { return rest_index_ >= 0; } |
| - |
| - bool has_simple_parameters() const { |
| - return has_simple_parameters_; |
| - } |
| - |
| - // TODO(caitp): manage this state in a better way. PreParser must be able to |
| - // communicate that the scope is non-simple, without allocating any parameters |
| - // as the Parser does. This is necessary to ensure that TC39's proposed early |
| - // error can be reported consistently regardless of whether lazily parsed or |
| - // not. |
| - void SetHasNonSimpleParameters() { |
| - DCHECK(is_function_scope()); |
| - has_simple_parameters_ = false; |
| - } |
| - |
| - // Retrieve `IsSimpleParameterList` of current or outer function. |
| - bool HasSimpleParameters() { |
| - Scope* scope = ClosureScope(); |
| - return !scope->is_function_scope() || scope->has_simple_parameters(); |
| - } |
| - |
| - // The local variable 'arguments' if we need to allocate it; NULL otherwise. |
| - Variable* arguments() const { |
| - DCHECK(!is_arrow_scope() || arguments_ == nullptr); |
| - return arguments_; |
| - } |
| - |
| - Variable* this_function_var() const { |
| - // This is only used in derived constructors atm. |
| - DCHECK(this_function_ == nullptr || |
| - (is_function_scope() && (IsClassConstructor(function_kind()) || |
| - IsConciseMethod(function_kind()) || |
| - IsAccessorFunction(function_kind())))); |
| - return this_function_; |
| - } |
| - |
| - // Declarations list. |
| - ZoneList<Declaration*>* declarations() { return &decls_; } |
| - |
| // inner_scope() and sibling() together implement the inner scope list of a |
| // scope. Inner scope points to the an inner scope of the function, and |
| // "sibling" points to a next inner scope of the outer scope of this scope. |
| @@ -520,9 +369,6 @@ class Scope: public ZoneObject { |
| // The scope immediately surrounding this scope, or NULL. |
| Scope* outer_scope() const { return outer_scope_; } |
| - // The ModuleDescriptor for this scope; only for module scopes. |
| - ModuleDescriptor* module() const { return module_descriptor_; } |
| - |
| const AstRawString* catch_variable_name() const { |
| DCHECK(is_catch_scope()); |
| DCHECK_EQ(1, num_var()); |
| @@ -572,18 +418,18 @@ class Scope: public ZoneObject { |
| // Find the first function, script, eval or (declaration) block scope. This is |
| // the scope where var declarations will be hoisted to in the implementation. |
| - Scope* DeclarationScope(); |
| + DeclarationScope* GetDeclarationScope(); |
| // Find the first non-block declaration scope. This should be either a script, |
| - // function, or eval scope. Same as DeclarationScope(), but skips |
| - // declaration "block" scopes. Used for differentiating associated |
| - // function objects (i.e., the scope for which a function prologue allocates |
| - // a context) or declaring temporaries. |
| - Scope* ClosureScope(); |
| + // function, or eval scope. Same as DeclarationScope(), but skips declaration |
| + // "block" scopes. Used for differentiating associated function objects (i.e., |
| + // the scope for which a function prologue allocates a context) or declaring |
| + // temporaries. |
| + DeclarationScope* GetClosureScope(); |
| // Find the first (non-arrow) function or script scope. This is where |
| // 'this' is bound, and what determines the function kind. |
| - Scope* ReceiverScope(); |
| + DeclarationScope* GetReceiverScope(); |
| Handle<ScopeInfo> GetScopeInfo(Isolate* isolate); |
| @@ -600,26 +446,8 @@ class Scope: public ZoneObject { |
| return variables_.Lookup(name) != NULL; |
| } |
| - bool IsDeclaredParameter(const AstRawString* name) { |
| - // If IsSimpleParameterList is false, duplicate parameters are not allowed, |
| - // however `arguments` may be allowed if function is not strict code. Thus, |
| - // the assumptions explained above do not hold. |
| - return params_.Contains(variables_.Lookup(name)); |
| - } |
| - |
| int num_var() const { return variables_.occupancy(); } |
| - SloppyBlockFunctionMap* sloppy_block_function_map() { |
| - return &sloppy_block_function_map_; |
| - } |
| - |
| - // To be called during parsing. Do just enough scope analysis that we can |
| - // discard the Scope for lazily compiled functions. In particular, this |
| - // records variables which cannot be resolved inside the Scope (we don't yet |
| - // know what they will resolve to since the outer Scopes are incomplete) and |
| - // migrates them into migrate_to. |
| - void AnalyzePartially(Scope* migrate_to, AstNodeFactory* ast_node_factory); |
| - |
| // --------------------------------------------------------------------------- |
| // Debugging. |
| @@ -633,31 +461,21 @@ class Scope: public ZoneObject { |
| void CheckZones(); |
| #endif |
| - // --------------------------------------------------------------------------- |
| - // Implementation. |
| + // Retrieve `IsSimpleParameterList` of current or outer function. |
| + bool HasSimpleParameters(); |
| + |
| private: |
| // Scope tree. |
| Scope* outer_scope_; // the immediately enclosing outer scope, or NULL |
| Scope* inner_scope_; // an inner scope of this scope |
| Scope* sibling_; // a sibling inner scope of the outer scope of this scope. |
| - // Debugging support. |
| -#ifdef DEBUG |
| - const AstRawString* scope_name_; |
| -#endif |
| - |
| // The variables declared in this scope: |
| // |
| // All user-declared variables (incl. parameters). For script scopes |
| // variables may be implicitly 'declared' by being used (possibly in |
| // an inner scope) with no intervening with statements or eval calls. |
| VariableMap variables_; |
| - // Compiler-allocated (user-invisible) temporaries. Due to the implementation |
| - // of RemoveTemporary(), may contain nulls, which must be skipped-over during |
| - // allocation and printing. |
| - ZoneList<Variable*> temps_; |
| - // Parameter list in source order. |
| - ZoneList<Variable*> params_; |
| // Variables that must be looked up dynamically. |
| DynamicScopePart* dynamics_; |
| // Unresolved variables referred to from this scope. The proxies themselves |
| @@ -665,26 +483,25 @@ class Scope: public ZoneObject { |
| VariableProxy* unresolved_; |
| // Declarations. |
| ZoneList<Declaration*> decls_; |
| - // Convenience variable. |
| - Variable* receiver_; |
| - // Function variable, if any; function scopes only. |
| - VariableDeclaration* function_; |
| - // new.target variable, function scopes only. |
| - Variable* new_target_; |
| - // Convenience variable; function scopes only. |
| - Variable* arguments_; |
| - // Convenience variable; Subclass constructor only |
| - Variable* this_function_; |
| - // Module descriptor; module scopes only. |
| - ModuleDescriptor* module_descriptor_; |
| - // Map of function names to lists of functions defined in sloppy blocks |
| - SloppyBlockFunctionMap sloppy_block_function_map_; |
| + // Serialized scope info support. |
| + Handle<ScopeInfo> scope_info_; |
| +// Debugging support. |
| +#ifdef DEBUG |
| + const AstRawString* scope_name_; |
| +#endif |
| + |
| + // Source positions. |
| + int start_position_; |
| + int end_position_; |
| + |
| + // Computed via AllocateVariables; function, block and catch scopes only. |
| + int num_stack_slots_; |
| + int num_heap_slots_; |
| + int num_global_slots_; |
| // The scope type. |
| const ScopeType scope_type_; |
| - // If the scope is a function scope, this is the function kind. |
| - const FunctionKind function_kind_; |
| // Scope-specific information computed during parsing. |
| // |
| @@ -707,7 +524,6 @@ class Scope: public ZoneObject { |
| // This scope's declarations might not be executed in order (e.g., switch). |
| bool scope_nonlinear_ : 1; |
| bool is_hidden_ : 1; |
| - bool has_simple_parameters_ : 1; |
| // Computed via PropagateScopeInfo. |
| bool outer_scope_calls_sloppy_eval_ : 1; |
| @@ -723,23 +539,6 @@ class Scope: public ZoneObject { |
| // True if it holds 'var' declarations. |
| bool is_declaration_scope_ : 1; |
| - // Source positions. |
| - int start_position_; |
| - int end_position_; |
| - |
| - // Computed via AllocateVariables; function, block and catch scopes only. |
| - int num_stack_slots_; |
| - int num_heap_slots_; |
| - int num_global_slots_; |
| - |
| - // Info about the parameter list of a function. |
| - int arity_; |
| - int rest_index_; |
| - Variable* rest_parameter_; |
| - |
| - // Serialized scope info support. |
| - Handle<ScopeInfo> scope_info_; |
| - |
| // Create a non-local variable with a given name. |
| // These variables are looked up dynamically at runtime. |
| Variable* NonLocal(const AstRawString* name, VariableMode mode); |
| @@ -805,9 +604,9 @@ class Scope: public ZoneObject { |
| // Tries to resolve local variables inside max_outer_scope; migrates those |
| // which cannot be resolved into migrate_to. |
| - void MigrateUnresolvableLocals(Scope* migrate_to, |
| + void MigrateUnresolvableLocals(DeclarationScope* migrate_to, |
| AstNodeFactory* ast_node_factory, |
| - Scope* max_outer_scope); |
| + DeclarationScope* max_outer_scope); |
| // Scope analysis. |
| void PropagateScopeInfo(bool outer_scope_calls_sloppy_eval); |
| @@ -820,7 +619,6 @@ class Scope: public ZoneObject { |
| // Variable allocation. |
| void AllocateStackSlot(Variable* var); |
| void AllocateHeapSlot(Variable* var); |
| - void AllocateParameterLocals(); |
| void AllocateNonParameterLocal(Variable* var, |
| AstValueFactory* ast_value_factory); |
| void AllocateDeclaredGlobal(Variable* var, |
| @@ -828,19 +626,6 @@ class Scope: public ZoneObject { |
| void AllocateNonParameterLocalsAndDeclaredGlobals( |
| AstValueFactory* ast_value_factory); |
| void AllocateVariablesRecursively(AstValueFactory* ast_value_factory); |
| - void AllocateParameter(Variable* var, int index); |
| - void AllocateReceiver(); |
| - |
| - // Resolve and fill in the allocation information for all variables |
| - // in this scopes. Must be called *after* all scopes have been |
| - // processed (parsed) to ensure that unresolved variables can be |
| - // resolved properly. |
| - // |
| - // In the case of code compiled and run using 'eval', the context |
| - // parameter is the context in which eval was called. In all other |
| - // cases the context parameter is an empty handle. |
| - MUST_USE_RESULT |
| - bool AllocateVariables(ParseInfo* info, AstNodeFactory* factory); |
| // Construct a scope based on the scope info. |
| Scope(Zone* zone, Scope* inner_scope, ScopeType type, |
| @@ -878,6 +663,246 @@ class Scope: public ZoneObject { |
| void DeserializeScopeInfo(Isolate* isolate, |
| AstValueFactory* ast_value_factory); |
| + friend class DeclarationScope; |
| +}; |
| + |
| +class DeclarationScope : public Scope { |
| + public: |
| + DeclarationScope(Zone* zone, Scope* outer_scope, ScopeType scope_type, |
| + FunctionKind function_kind = kNormalFunction); |
| + DeclarationScope(Zone* zone, Scope* inner_scope, ScopeType scope_type, |
| + Handle<ScopeInfo> scope_info); |
| + |
| + bool IsDeclaredParameter(const AstRawString* name) { |
| + // If IsSimpleParameterList is false, duplicate parameters are not allowed, |
| + // however `arguments` may be allowed if function is not strict code. Thus, |
| + // the assumptions explained above do not hold. |
| + return params_.Contains(variables_.Lookup(name)); |
| + } |
| + |
| + FunctionKind function_kind() const { return function_kind_; } |
| + |
| + bool is_arrow_scope() const { |
| + return is_function_scope() && IsArrowFunction(function_kind_); |
| + } |
| + |
| + bool NeedsHomeObject() const { |
| + return scope_uses_super_property_ || |
| + ((scope_calls_eval_ || inner_scope_calls_eval_) && |
| + (IsConciseMethod(function_kind()) || |
| + IsAccessorFunction(function_kind()) || |
| + IsClassConstructor(function_kind()))); |
| + } |
| + |
| + // The ModuleDescriptor for this scope; only for module scopes. |
| + // TODO(verwaest): Move to ModuleScope? |
| + ModuleDescriptor* module() const { return module_descriptor_; } |
| + |
| + void DeclareThis(AstValueFactory* ast_value_factory); |
| + void DeclareDefaultFunctionVariables(AstValueFactory* ast_value_factory); |
| + |
| + // This lookup corresponds to a lookup in the "intermediate" scope sitting |
| + // between this scope and the outer scope. (ECMA-262, 3rd., requires that |
| + // the name of named function literal is kept in an intermediate scope |
| + // in between this scope and the next outer scope.) |
| + Variable* LookupFunctionVar(const AstRawString* name, |
| + AstNodeFactory* factory); |
| + |
| + // Declare the function variable for a function literal. This variable |
| + // is in an intermediate scope between this function scope and the the |
| + // outer scope. Only possible for function scopes; at most one variable. |
| + void DeclareFunctionVar(VariableDeclaration* declaration) { |
| + DCHECK(is_function_scope()); |
| + // Handle implicit declaration of the function name in named function |
| + // expressions before other declarations. |
| + declarations()->InsertAt(0, declaration, zone()); |
| + function_ = declaration; |
| + } |
| + |
| + // Declare a parameter in this scope. When there are duplicated |
| + // parameters the rightmost one 'wins'. However, the implementation |
| + // expects all parameters to be declared and from left to right. |
| + Variable* DeclareParameter(const AstRawString* name, VariableMode mode, |
| + bool is_optional, bool is_rest, bool* is_duplicate, |
| + AstValueFactory* ast_value_factory); |
| + |
| + // Declare an implicit global variable in this scope which must be a |
| + // script scope. The variable was introduced (possibly from an inner |
| + // scope) by a reference to an unresolved variable with no intervening |
| + // with statements or eval calls. |
| + Variable* DeclareDynamicGlobal(const AstRawString* name); |
| + |
| + // The variable corresponding to the 'this' value. |
| + Variable* receiver() { |
| + DCHECK(has_this_declaration()); |
| + DCHECK_NOT_NULL(receiver_); |
| + return receiver_; |
| + } |
| + |
| + // TODO(wingo): Add a GLOBAL_SCOPE scope type which will lexically allocate |
| + // "this" (and no other variable) on the native context. Script scopes then |
| + // will not have a "this" declaration. |
| + bool has_this_declaration() const { |
| + return (is_function_scope() && !is_arrow_scope()) || is_module_scope(); |
| + } |
| + |
| + // The variable corresponding to the 'new.target' value. |
| + Variable* new_target_var() { return new_target_; } |
| + |
| + // The variable holding the function literal for named function |
| + // literals, or NULL. Only valid for function scopes. |
| + VariableDeclaration* function() const { |
| + DCHECK(is_function_scope()); |
| + return function_; |
| + } |
| + |
| + // Parameters. The left-most parameter has index 0. |
| + // Only valid for function scopes. |
| + Variable* parameter(int index) const { |
| + DCHECK(is_function_scope()); |
| + return params_[index]; |
| + } |
| + |
| + // Returns the default function arity excluding default or rest parameters. |
| + int default_function_length() const { return arity_; } |
| + |
| + // Returns the number of formal parameters, up to but not including the |
| + // rest parameter index (if the function has rest parameters), i.e. it |
| + // says 2 for |
| + // |
| + // function foo(a, b) { ... } |
| + // |
| + // and |
| + // |
| + // function foo(a, b, ...c) { ... } |
| + // |
| + // but for |
| + // |
| + // function foo(a, b, c = 1) { ... } |
| + // |
| + // we return 3 here. |
| + int num_parameters() const { |
| + return has_rest_parameter() ? params_.length() - 1 : params_.length(); |
| + } |
| + |
| + // A function can have at most one rest parameter. Returns Variable* or NULL. |
| + Variable* rest_parameter(int* index) const { |
| + *index = rest_index_; |
| + if (rest_index_ < 0) return NULL; |
| + return rest_parameter_; |
| + } |
| + |
| + bool has_rest_parameter() const { return rest_index_ >= 0; } |
| + |
| + bool has_simple_parameters() const { return has_simple_parameters_; } |
| + |
| + // TODO(caitp): manage this state in a better way. PreParser must be able to |
| + // communicate that the scope is non-simple, without allocating any parameters |
| + // as the Parser does. This is necessary to ensure that TC39's proposed early |
| + // error can be reported consistently regardless of whether lazily parsed or |
| + // not. |
| + void SetHasNonSimpleParameters() { |
| + DCHECK(is_function_scope()); |
| + has_simple_parameters_ = false; |
| + } |
| + |
| + // The local variable 'arguments' if we need to allocate it; NULL otherwise. |
| + Variable* arguments() const { |
| + DCHECK(!is_arrow_scope() || arguments_ == nullptr); |
| + return arguments_; |
| + } |
| + |
| + Variable* this_function_var() const { |
| + // This is only used in derived constructors atm. |
| + DCHECK(this_function_ == nullptr || |
| + (is_function_scope() && (IsClassConstructor(function_kind()) || |
| + IsConciseMethod(function_kind()) || |
| + IsAccessorFunction(function_kind())))); |
| + return this_function_; |
| + } |
| + |
| + // Remove a temporary variable. This is for adjusting the scope of |
| + // temporaries used when desugaring parameter initializers. |
| + // Returns the index at which it was found in this scope, or -1 if |
| + // it was not found. |
| + int RemoveTemporary(Variable* var); |
| + |
| + // Adds a temporary variable in this scope's TemporaryScope. This is for |
| + // adjusting the scope of temporaries used when desugaring parameter |
| + // initializers. |
| + void AddTemporary(Variable* var) { |
| + // Temporaries are only placed in ClosureScopes. |
| + DCHECK_EQ(GetClosureScope(), this); |
| + temps_.Add(var, zone()); |
| + } |
| + |
| + ZoneList<Variable*>* temps() { return &temps_; } |
| + |
| + SloppyBlockFunctionMap* sloppy_block_function_map() { |
| + return &sloppy_block_function_map_; |
| + } |
| + |
| + // Resolve and fill in the allocation information for all variables |
| + // in this scopes. Must be called *after* all scopes have been |
| + // processed (parsed) to ensure that unresolved variables can be |
| + // resolved properly. |
| + // |
| + // In the case of code compiled and run using 'eval', the context |
| + // parameter is the context in which eval was called. In all other |
| + // cases the context parameter is an empty handle. |
| + MUST_USE_RESULT |
| + bool AllocateVariables(ParseInfo* info, AstNodeFactory* factory); |
| + |
| + // To be called during parsing. Do just enough scope analysis that we can |
| + // discard the Scope for lazily compiled functions. In particular, this |
| + // records variables which cannot be resolved inside the Scope (we don't yet |
| + // know what they will resolve to since the outer Scopes are incomplete) and |
| + // migrates them into migrate_to. |
| + void AnalyzePartially(DeclarationScope* migrate_to, |
| + AstNodeFactory* ast_node_factory); |
| + |
| +#ifdef DEBUG |
| + void PrintParameters(); |
| +#endif |
| + |
| + void AllocateLocals(AstValueFactory* ast_value_factory); |
| + void AllocateParameterLocals(); |
| + void AllocateReceiver(); |
| + |
| + private: |
| + void AllocateParameter(Variable* var, int index); |
| + |
| + void SetDefaults(); |
| + |
| + // If the scope is a function scope, this is the function kind. |
| + const FunctionKind function_kind_; |
| + |
| + bool has_simple_parameters_ : 1; |
|
Toon Verwaest
2016/08/05 13:42:13
This is the actual change that valgrind was fallin
|
| + |
| + // Info about the parameter list of a function. |
| + int arity_; |
| + int rest_index_; |
| + Variable* rest_parameter_; |
| + // Compiler-allocated (user-invisible) temporaries. Due to the implementation |
| + // of RemoveTemporary(), may contain nulls, which must be skipped-over during |
| + // allocation and printing. |
| + ZoneList<Variable*> temps_; |
| + // Parameter list in source order. |
| + ZoneList<Variable*> params_; |
| + // Map of function names to lists of functions defined in sloppy blocks |
| + SloppyBlockFunctionMap sloppy_block_function_map_; |
| + // Convenience variable. |
| + Variable* receiver_; |
| + // Function variable, if any; function scopes only. |
| + VariableDeclaration* function_; |
| + // new.target variable, function scopes only. |
| + Variable* new_target_; |
| + // Convenience variable; function scopes only. |
| + Variable* arguments_; |
| + // Convenience variable; Subclass constructor only |
| + Variable* this_function_; |
| + // Module descriptor; module scopes only. |
| + ModuleDescriptor* module_descriptor_; |
| PendingCompilationErrorHandler pending_error_handler_; |
| }; |