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 |