| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_AST_SCOPES_H_ | 5 #ifndef V8_AST_SCOPES_H_ |
| 6 #define V8_AST_SCOPES_H_ | 6 #define V8_AST_SCOPES_H_ |
| 7 | 7 |
| 8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
| 9 #include "src/pending-compilation-error-handler.h" | 9 #include "src/pending-compilation-error-handler.h" |
| 10 #include "src/zone.h" | 10 #include "src/zone.h" |
| 11 | 11 |
| 12 namespace v8 { | 12 namespace v8 { |
| 13 namespace internal { | 13 namespace internal { |
| 14 | 14 |
| 15 class ParseInfo; | 15 class ParseInfo; |
| 16 | 16 |
| 17 // A hash map to support fast variable declaration and lookup. | 17 // A hash map to support fast variable declaration and lookup. |
| 18 class VariableMap: public ZoneHashMap { | 18 class VariableMap : public ZoneHashMap { |
| 19 public: | 19 public: |
| 20 explicit VariableMap(Zone* zone); | 20 explicit VariableMap(Zone* zone); |
| 21 | 21 |
| 22 virtual ~VariableMap(); | 22 virtual ~VariableMap(); |
| 23 | 23 |
| 24 Variable* Declare(Scope* scope, const AstRawString* name, VariableMode mode, | 24 Variable* Declare(Scope* scope, const AstRawString* name, VariableMode mode, |
| 25 Variable::Kind kind, InitializationFlag initialization_flag, | 25 Variable::Kind kind, InitializationFlag initialization_flag, |
| 26 MaybeAssignedFlag maybe_assigned_flag = kNotAssigned, | 26 MaybeAssignedFlag maybe_assigned_flag = kNotAssigned, |
| 27 int declaration_group_start = -1); | 27 int declaration_group_start = -1); |
| 28 | 28 |
| 29 Variable* Lookup(const AstRawString* name); | 29 Variable* Lookup(const AstRawString* name); |
| 30 | 30 |
| 31 Zone* zone() const { return zone_; } | 31 Zone* zone() const { return zone_; } |
| 32 | 32 |
| 33 private: | 33 private: |
| 34 Zone* zone_; | 34 Zone* zone_; |
| 35 }; | 35 }; |
| 36 | 36 |
| 37 | 37 |
| 38 // The dynamic scope part holds hash maps for the variables that will | 38 // The dynamic scope part holds hash maps for the variables that will |
| 39 // be looked up dynamically from within eval and with scopes. The objects | 39 // be looked up dynamically from within eval and with scopes. The objects |
| 40 // are allocated on-demand from Scope::NonLocal to avoid wasting memory | 40 // are allocated on-demand from Scope::NonLocal to avoid wasting memory |
| 41 // and setup time for scopes that don't need them. | 41 // and setup time for scopes that don't need them. |
| 42 class DynamicScopePart : public ZoneObject { | 42 class DynamicScopePart : public ZoneObject { |
| 43 public: | 43 public: |
| 44 explicit DynamicScopePart(Zone* zone) { | 44 explicit DynamicScopePart(Zone* zone) { |
| 45 for (int i = 0; i < 3; i++) | 45 for (int i = 0; i < 3; i++) |
| 46 maps_[i] = new(zone->New(sizeof(VariableMap))) VariableMap(zone); | 46 maps_[i] = new (zone->New(sizeof(VariableMap))) VariableMap(zone); |
| 47 } | 47 } |
| 48 | 48 |
| 49 VariableMap* GetMap(VariableMode mode) { | 49 VariableMap* GetMap(VariableMode mode) { |
| 50 int index = mode - DYNAMIC; | 50 int index = mode - DYNAMIC; |
| 51 DCHECK(index >= 0 && index < 3); | 51 DCHECK(index >= 0 && index < 3); |
| 52 return maps_[index]; | 52 return maps_[index]; |
| 53 } | 53 } |
| 54 | 54 |
| 55 private: | 55 private: |
| 56 VariableMap *maps_[3]; | 56 VariableMap* maps_[3]; |
| 57 }; | 57 }; |
| 58 | 58 |
| 59 | 59 |
| 60 // Sloppy block-scoped function declarations to var-bind | 60 // Sloppy block-scoped function declarations to var-bind |
| 61 class SloppyBlockFunctionMap : public ZoneHashMap { | 61 class SloppyBlockFunctionMap : public ZoneHashMap { |
| 62 public: | 62 public: |
| 63 explicit SloppyBlockFunctionMap(Zone* zone); | 63 explicit SloppyBlockFunctionMap(Zone* zone); |
| 64 | 64 |
| 65 virtual ~SloppyBlockFunctionMap(); | 65 virtual ~SloppyBlockFunctionMap(); |
| 66 | 66 |
| 67 void Declare(const AstRawString* name, | 67 void Declare(const AstRawString* name, |
| 68 SloppyBlockFunctionStatement* statement); | 68 SloppyBlockFunctionStatement* statement); |
| 69 | 69 |
| 70 typedef ZoneVector<SloppyBlockFunctionStatement*> Vector; | 70 typedef ZoneVector<SloppyBlockFunctionStatement*> Vector; |
| 71 | 71 |
| 72 private: | 72 private: |
| 73 Zone* zone_; | 73 Zone* zone_; |
| 74 }; | 74 }; |
| 75 | 75 |
| 76 | 76 |
| 77 // Global invariants after AST construction: Each reference (i.e. identifier) | 77 // Global invariants after AST construction: Each reference (i.e. identifier) |
| 78 // to a JavaScript variable (including global properties) is represented by a | 78 // to a JavaScript variable (including global properties) is represented by a |
| 79 // VariableProxy node. Immediately after AST construction and before variable | 79 // VariableProxy node. Immediately after AST construction and before variable |
| 80 // allocation, most VariableProxy nodes are "unresolved", i.e. not bound to a | 80 // allocation, most VariableProxy nodes are "unresolved", i.e. not bound to a |
| 81 // corresponding variable (though some are bound during parse time). Variable | 81 // corresponding variable (though some are bound during parse time). Variable |
| 82 // allocation binds each unresolved VariableProxy to one Variable and assigns | 82 // allocation binds each unresolved VariableProxy to one Variable and assigns |
| 83 // a location. Note that many VariableProxy nodes may refer to the same Java- | 83 // a location. Note that many VariableProxy nodes may refer to the same Java- |
| 84 // Script variable. | 84 // Script variable. |
| 85 | 85 |
| 86 class Scope: public ZoneObject { | 86 class Scope : public ZoneObject { |
| 87 public: | 87 public: |
| 88 // --------------------------------------------------------------------------- | 88 // --------------------------------------------------------------------------- |
| 89 // Construction | 89 // Construction |
| 90 | 90 |
| 91 Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type, | 91 Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type, |
| 92 AstValueFactory* value_factory, | 92 AstValueFactory* value_factory, |
| 93 FunctionKind function_kind = kNormalFunction); | 93 FunctionKind function_kind = kNormalFunction); |
| 94 | 94 |
| 95 // Compute top scope and allocate variables. For lazy compilation the top | 95 // Compute top scope and allocate variables. For lazy compilation the top |
| 96 // scope only contains the single lazily compiled function, so this | 96 // scope only contains the single lazily compiled function, so this |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 DCHECK(is_function_scope()); | 147 DCHECK(is_function_scope()); |
| 148 // Handle implicit declaration of the function name in named function | 148 // Handle implicit declaration of the function name in named function |
| 149 // expressions before other declarations. | 149 // expressions before other declarations. |
| 150 decls_.InsertAt(0, declaration, zone()); | 150 decls_.InsertAt(0, declaration, zone()); |
| 151 function_ = declaration; | 151 function_ = declaration; |
| 152 } | 152 } |
| 153 | 153 |
| 154 // Declare a parameter in this scope. When there are duplicated | 154 // Declare a parameter in this scope. When there are duplicated |
| 155 // parameters the rightmost one 'wins'. However, the implementation | 155 // parameters the rightmost one 'wins'. However, the implementation |
| 156 // expects all parameters to be declared and from left to right. | 156 // expects all parameters to be declared and from left to right. |
| 157 Variable* DeclareParameter( | 157 Variable* DeclareParameter(const AstRawString* name, VariableMode mode, |
| 158 const AstRawString* name, VariableMode mode, | 158 bool is_optional, bool is_rest, |
| 159 bool is_optional, bool is_rest, bool* is_duplicate); | 159 bool* is_duplicate); |
| 160 | 160 |
| 161 // Declare a local variable in this scope. If the variable has been | 161 // Declare a local variable in this scope. If the variable has been |
| 162 // declared before, the previously declared variable is returned. | 162 // declared before, the previously declared variable is returned. |
| 163 Variable* DeclareLocal(const AstRawString* name, VariableMode mode, | 163 Variable* DeclareLocal(const AstRawString* name, VariableMode mode, |
| 164 InitializationFlag init_flag, Variable::Kind kind, | 164 InitializationFlag init_flag, Variable::Kind kind, |
| 165 MaybeAssignedFlag maybe_assigned_flag = kNotAssigned, | 165 MaybeAssignedFlag maybe_assigned_flag = kNotAssigned, |
| 166 int declaration_group_start = -1); | 166 int declaration_group_start = -1); |
| 167 | 167 |
| 168 // Declare an implicit global variable in this scope which must be a | 168 // Declare an implicit global variable in this scope which must be a |
| 169 // script scope. The variable was introduced (possibly from an inner | 169 // script scope. The variable was introduced (possibly from an inner |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 // end position: end position of last token of 'stmt' | 292 // end position: end position of last token of 'stmt' |
| 293 // * For the scope of a switch statement | 293 // * For the scope of a switch statement |
| 294 // switch (tag) { cases } | 294 // switch (tag) { cases } |
| 295 // start position: start position of '{' | 295 // start position: start position of '{' |
| 296 // end position: end position of '}' | 296 // end position: end position of '}' |
| 297 int start_position() const { return start_position_; } | 297 int start_position() const { return start_position_; } |
| 298 void set_start_position(int statement_pos) { | 298 void set_start_position(int statement_pos) { |
| 299 start_position_ = statement_pos; | 299 start_position_ = statement_pos; |
| 300 } | 300 } |
| 301 int end_position() const { return end_position_; } | 301 int end_position() const { return end_position_; } |
| 302 void set_end_position(int statement_pos) { | 302 void set_end_position(int statement_pos) { end_position_ = statement_pos; } |
| 303 end_position_ = statement_pos; | |
| 304 } | |
| 305 | 303 |
| 306 // In some cases we want to force context allocation for a whole scope. | 304 // In some cases we want to force context allocation for a whole scope. |
| 307 void ForceContextAllocation() { | 305 void ForceContextAllocation() { |
| 308 DCHECK(!already_resolved()); | 306 DCHECK(!already_resolved()); |
| 309 force_context_allocation_ = true; | 307 force_context_allocation_ = true; |
| 310 } | 308 } |
| 311 bool has_forced_context_allocation() const { | 309 bool has_forced_context_allocation() const { |
| 312 return force_context_allocation_; | 310 return force_context_allocation_; |
| 313 } | 311 } |
| 314 | 312 |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 420 | 418 |
| 421 int num_parameters() const { return params_.length(); } | 419 int num_parameters() const { return params_.length(); } |
| 422 | 420 |
| 423 // A function can have at most one rest parameter. Returns Variable* or NULL. | 421 // A function can have at most one rest parameter. Returns Variable* or NULL. |
| 424 Variable* rest_parameter(int* index) const { | 422 Variable* rest_parameter(int* index) const { |
| 425 *index = rest_index_; | 423 *index = rest_index_; |
| 426 if (rest_index_ < 0) return NULL; | 424 if (rest_index_ < 0) return NULL; |
| 427 return rest_parameter_; | 425 return rest_parameter_; |
| 428 } | 426 } |
| 429 | 427 |
| 430 bool has_rest_parameter() const { | 428 bool has_rest_parameter() const { return rest_index_ >= 0; } |
| 431 return rest_index_ >= 0; | |
| 432 } | |
| 433 | 429 |
| 434 bool has_simple_parameters() const { | 430 bool has_simple_parameters() const { return has_simple_parameters_; } |
| 435 return has_simple_parameters_; | |
| 436 } | |
| 437 | 431 |
| 438 // TODO(caitp): manage this state in a better way. PreParser must be able to | 432 // TODO(caitp): manage this state in a better way. PreParser must be able to |
| 439 // communicate that the scope is non-simple, without allocating any parameters | 433 // communicate that the scope is non-simple, without allocating any parameters |
| 440 // as the Parser does. This is necessary to ensure that TC39's proposed early | 434 // as the Parser does. This is necessary to ensure that TC39's proposed early |
| 441 // error can be reported consistently regardless of whether lazily parsed or | 435 // error can be reported consistently regardless of whether lazily parsed or |
| 442 // not. | 436 // not. |
| 443 void SetHasNonSimpleParameters() { | 437 void SetHasNonSimpleParameters() { |
| 444 DCHECK(is_function_scope()); | 438 DCHECK(is_function_scope()); |
| 445 has_simple_parameters_ = false; | 439 has_simple_parameters_ = false; |
| 446 } | 440 } |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 510 int ContextLocalCount() const; | 504 int ContextLocalCount() const; |
| 511 int ContextGlobalCount() const; | 505 int ContextGlobalCount() const; |
| 512 | 506 |
| 513 // For script scopes, the number of module literals (including nested ones). | 507 // For script scopes, the number of module literals (including nested ones). |
| 514 int num_modules() const { return num_modules_; } | 508 int num_modules() const { return num_modules_; } |
| 515 | 509 |
| 516 // For module scopes, the host scope's internal variable binding this module. | 510 // For module scopes, the host scope's internal variable binding this module. |
| 517 Variable* module_var() const { return module_var_; } | 511 Variable* module_var() const { return module_var_; } |
| 518 | 512 |
| 519 // Make sure this scope and all outer scopes are eagerly compiled. | 513 // Make sure this scope and all outer scopes are eagerly compiled. |
| 520 void ForceEagerCompilation() { force_eager_compilation_ = true; } | 514 void ForceEagerCompilation() { force_eager_compilation_ = true; } |
| 521 | 515 |
| 522 // Determine if we can parse a function literal in this scope lazily. | 516 // Determine if we can parse a function literal in this scope lazily. |
| 523 bool AllowsLazyParsing() const; | 517 bool AllowsLazyParsing() const; |
| 524 | 518 |
| 525 // Determine if we can use lazy compilation for this scope. | 519 // Determine if we can use lazy compilation for this scope. |
| 526 bool AllowsLazyCompilation() const; | 520 bool AllowsLazyCompilation() const; |
| 527 | 521 |
| 528 // Determine if we can use lazy compilation for this scope without a context. | 522 // Determine if we can use lazy compilation for this scope without a context. |
| 529 bool AllowsLazyCompilationWithoutContext() const; | 523 bool AllowsLazyCompilationWithoutContext() const; |
| 530 | 524 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 582 | 576 |
| 583 SloppyBlockFunctionMap* sloppy_block_function_map() { | 577 SloppyBlockFunctionMap* sloppy_block_function_map() { |
| 584 return &sloppy_block_function_map_; | 578 return &sloppy_block_function_map_; |
| 585 } | 579 } |
| 586 | 580 |
| 587 // Error handling. | 581 // Error handling. |
| 588 void ReportMessage(int start_position, int end_position, | 582 void ReportMessage(int start_position, int end_position, |
| 589 MessageTemplate::Template message, | 583 MessageTemplate::Template message, |
| 590 const AstRawString* arg); | 584 const AstRawString* arg); |
| 591 | 585 |
| 592 // --------------------------------------------------------------------------- | 586 // --------------------------------------------------------------------------- |
| 593 // Debugging. | 587 // Debugging. |
| 594 | 588 |
| 595 #ifdef DEBUG | 589 #ifdef DEBUG |
| 596 void Print(int n = 0); // n = indentation; n < 0 => don't print recursively | 590 void Print(int n = 0); // n = indentation; n < 0 => don't print recursively |
| 597 #endif | 591 #endif |
| 598 | 592 |
| 599 // --------------------------------------------------------------------------- | 593 // --------------------------------------------------------------------------- |
| 600 // Implementation. | 594 // Implementation. |
| 601 private: | 595 private: |
| 602 // Scope tree. | 596 // Scope tree. |
| 603 Scope* outer_scope_; // the immediately enclosing outer scope, or NULL | 597 Scope* outer_scope_; // the immediately enclosing outer scope, or NULL |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 843 | 837 |
| 844 // For tracking which classes are declared consecutively. Needed for strong | 838 // For tracking which classes are declared consecutively. Needed for strong |
| 845 // mode. | 839 // mode. |
| 846 int class_declaration_group_start_; | 840 int class_declaration_group_start_; |
| 847 }; | 841 }; |
| 848 | 842 |
| 849 } // namespace internal | 843 } // namespace internal |
| 850 } // namespace v8 | 844 } // namespace v8 |
| 851 | 845 |
| 852 #endif // V8_AST_SCOPES_H_ | 846 #endif // V8_AST_SCOPES_H_ |
| OLD | NEW |