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_SCOPES_H_ | 5 #ifndef V8_SCOPES_H_ |
6 #define V8_SCOPES_H_ | 6 #define V8_SCOPES_H_ |
7 | 7 |
8 #include "src/ast.h" | 8 #include "src/ast.h" |
9 #include "src/zone.h" | 9 #include "src/zone.h" |
10 | 10 |
11 namespace v8 { | 11 namespace v8 { |
12 namespace internal { | 12 namespace internal { |
13 | 13 |
14 class CompilationInfo; | 14 class CompilationInfo; |
15 | 15 |
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, | 24 Variable* Declare(Scope* scope, |
25 Handle<String> name, | 25 const AstRawString* name, |
26 VariableMode mode, | 26 VariableMode mode, |
27 bool is_valid_lhs, | 27 bool is_valid_lhs, |
28 Variable::Kind kind, | 28 Variable::Kind kind, |
29 InitializationFlag initialization_flag, | 29 InitializationFlag initialization_flag, |
30 Interface* interface = Interface::NewValue()); | 30 Interface* interface = Interface::NewValue()); |
31 | 31 |
32 Variable* Lookup(Handle<String> name); | 32 Variable* Lookup(const AstRawString* name); |
33 | 33 |
34 Zone* zone() const { return zone_; } | 34 Zone* zone() const { return zone_; } |
35 | 35 |
36 private: | 36 private: |
37 Zone* zone_; | 37 Zone* zone_; |
38 }; | 38 }; |
39 | 39 |
40 | 40 |
41 // The dynamic scope part holds hash maps for the variables that will | 41 // The dynamic scope part holds hash maps for the variables that will |
42 // be looked up dynamically from within eval and with scopes. The objects | 42 // be looked up dynamically from within eval and with scopes. The objects |
(...skipping 24 matching lines...) Expand all Loading... |
67 // corresponding variable (though some are bound during parse time). Variable | 67 // corresponding variable (though some are bound during parse time). Variable |
68 // allocation binds each unresolved VariableProxy to one Variable and assigns | 68 // allocation binds each unresolved VariableProxy to one Variable and assigns |
69 // a location. Note that many VariableProxy nodes may refer to the same Java- | 69 // a location. Note that many VariableProxy nodes may refer to the same Java- |
70 // Script variable. | 70 // Script variable. |
71 | 71 |
72 class Scope: public ZoneObject { | 72 class Scope: public ZoneObject { |
73 public: | 73 public: |
74 // --------------------------------------------------------------------------- | 74 // --------------------------------------------------------------------------- |
75 // Construction | 75 // Construction |
76 | 76 |
77 Scope(Scope* outer_scope, ScopeType scope_type, Zone* zone); | 77 Scope(Scope* outer_scope, ScopeType scope_type, |
| 78 AstValueFactory* value_factory, Zone* zone); |
78 | 79 |
79 // Compute top scope and allocate variables. For lazy compilation the top | 80 // Compute top scope and allocate variables. For lazy compilation the top |
80 // scope only contains the single lazily compiled function, so this | 81 // scope only contains the single lazily compiled function, so this |
81 // doesn't re-allocate variables repeatedly. | 82 // doesn't re-allocate variables repeatedly. |
82 static bool Analyze(CompilationInfo* info); | 83 static bool Analyze(CompilationInfo* info); |
83 | 84 |
84 static Scope* DeserializeScopeChain(Context* context, Scope* global_scope, | 85 static Scope* DeserializeScopeChain(Context* context, Scope* global_scope, |
85 Zone* zone); | 86 Zone* zone); |
86 | 87 |
87 // The scope name is only used for printing/debugging. | 88 // The scope name is only used for printing/debugging. |
88 void SetScopeName(Handle<String> scope_name) { scope_name_ = scope_name; } | 89 void SetScopeName(const AstRawString* scope_name) { |
| 90 scope_name_ = scope_name; |
| 91 } |
89 | 92 |
90 void Initialize(); | 93 void Initialize(); |
91 | 94 |
92 // Checks if the block scope is redundant, i.e. it does not contain any | 95 // Checks if the block scope is redundant, i.e. it does not contain any |
93 // block scoped declarations. In that case it is removed from the scope | 96 // block scoped declarations. In that case it is removed from the scope |
94 // tree and its children are reparented. | 97 // tree and its children are reparented. |
95 Scope* FinalizeBlockScope(); | 98 Scope* FinalizeBlockScope(); |
96 | 99 |
97 Zone* zone() const { return zone_; } | 100 Zone* zone() const { return zone_; } |
98 | 101 |
99 // --------------------------------------------------------------------------- | 102 // --------------------------------------------------------------------------- |
100 // Declarations | 103 // Declarations |
101 | 104 |
102 // Lookup a variable in this scope. Returns the variable or NULL if not found. | 105 // Lookup a variable in this scope. Returns the variable or NULL if not found. |
103 Variable* LookupLocal(Handle<String> name); | 106 Variable* LookupLocal(const AstRawString* name); |
104 | 107 |
105 // This lookup corresponds to a lookup in the "intermediate" scope sitting | 108 // This lookup corresponds to a lookup in the "intermediate" scope sitting |
106 // between this scope and the outer scope. (ECMA-262, 3rd., requires that | 109 // between this scope and the outer scope. (ECMA-262, 3rd., requires that |
107 // the name of named function literal is kept in an intermediate scope | 110 // the name of named function literal is kept in an intermediate scope |
108 // in between this scope and the next outer scope.) | 111 // in between this scope and the next outer scope.) |
109 Variable* LookupFunctionVar(Handle<String> name, | 112 Variable* LookupFunctionVar(const AstRawString* name, |
110 AstNodeFactory<AstNullVisitor>* factory); | 113 AstNodeFactory<AstNullVisitor>* factory); |
111 | 114 |
112 // Lookup a variable in this scope or outer scopes. | 115 // Lookup a variable in this scope or outer scopes. |
113 // Returns the variable or NULL if not found. | 116 // Returns the variable or NULL if not found. |
114 Variable* Lookup(Handle<String> name); | 117 Variable* Lookup(const AstRawString* name); |
115 | 118 |
116 // Declare the function variable for a function literal. This variable | 119 // Declare the function variable for a function literal. This variable |
117 // is in an intermediate scope between this function scope and the the | 120 // is in an intermediate scope between this function scope and the the |
118 // outer scope. Only possible for function scopes; at most one variable. | 121 // outer scope. Only possible for function scopes; at most one variable. |
119 void DeclareFunctionVar(VariableDeclaration* declaration) { | 122 void DeclareFunctionVar(VariableDeclaration* declaration) { |
120 ASSERT(is_function_scope()); | 123 ASSERT(is_function_scope()); |
121 function_ = declaration; | 124 function_ = declaration; |
122 } | 125 } |
123 | 126 |
124 // Declare a parameter in this scope. When there are duplicated | 127 // Declare a parameter in this scope. When there are duplicated |
125 // parameters the rightmost one 'wins'. However, the implementation | 128 // parameters the rightmost one 'wins'. However, the implementation |
126 // expects all parameters to be declared and from left to right. | 129 // expects all parameters to be declared and from left to right. |
127 void DeclareParameter(Handle<String> name, VariableMode mode); | 130 void DeclareParameter(const AstRawString* name, VariableMode mode); |
128 | 131 |
129 // Declare a local variable in this scope. If the variable has been | 132 // Declare a local variable in this scope. If the variable has been |
130 // declared before, the previously declared variable is returned. | 133 // declared before, the previously declared variable is returned. |
131 Variable* DeclareLocal(Handle<String> name, | 134 Variable* DeclareLocal(const AstRawString* name, |
132 VariableMode mode, | 135 VariableMode mode, |
133 InitializationFlag init_flag, | 136 InitializationFlag init_flag, |
134 Interface* interface = Interface::NewValue()); | 137 Interface* interface = Interface::NewValue()); |
135 | 138 |
136 // Declare an implicit global variable in this scope which must be a | 139 // Declare an implicit global variable in this scope which must be a |
137 // global scope. The variable was introduced (possibly from an inner | 140 // global scope. The variable was introduced (possibly from an inner |
138 // scope) by a reference to an unresolved variable with no intervening | 141 // scope) by a reference to an unresolved variable with no intervening |
139 // with statements or eval calls. | 142 // with statements or eval calls. |
140 Variable* DeclareDynamicGlobal(Handle<String> name); | 143 Variable* DeclareDynamicGlobal(const AstRawString* name); |
141 | 144 |
142 // Create a new unresolved variable. | 145 // Create a new unresolved variable. |
143 template<class Visitor> | 146 template<class Visitor> |
144 VariableProxy* NewUnresolved(AstNodeFactory<Visitor>* factory, | 147 VariableProxy* NewUnresolved(AstNodeFactory<Visitor>* factory, |
145 Handle<String> name, | 148 const AstRawString* name, |
146 Interface* interface = Interface::NewValue(), | 149 Interface* interface = Interface::NewValue(), |
147 int position = RelocInfo::kNoPosition) { | 150 int position = RelocInfo::kNoPosition) { |
148 // Note that we must not share the unresolved variables with | 151 // Note that we must not share the unresolved variables with |
149 // the same name because they may be removed selectively via | 152 // the same name because they may be removed selectively via |
150 // RemoveUnresolved(). | 153 // RemoveUnresolved(). |
151 ASSERT(!already_resolved()); | 154 ASSERT(!already_resolved()); |
152 VariableProxy* proxy = | 155 VariableProxy* proxy = |
153 factory->NewVariableProxy(name, false, interface, position); | 156 factory->NewVariableProxy(name, false, interface, position); |
154 unresolved_.Add(proxy, zone_); | 157 unresolved_.Add(proxy, zone_); |
155 return proxy; | 158 return proxy; |
156 } | 159 } |
157 | 160 |
158 // Remove a unresolved variable. During parsing, an unresolved variable | 161 // Remove a unresolved variable. During parsing, an unresolved variable |
159 // may have been added optimistically, but then only the variable name | 162 // may have been added optimistically, but then only the variable name |
160 // was used (typically for labels). If the variable was not declared, the | 163 // was used (typically for labels). If the variable was not declared, the |
161 // addition introduced a new unresolved variable which may end up being | 164 // addition introduced a new unresolved variable which may end up being |
162 // allocated globally as a "ghost" variable. RemoveUnresolved removes | 165 // allocated globally as a "ghost" variable. RemoveUnresolved removes |
163 // such a variable again if it was added; otherwise this is a no-op. | 166 // such a variable again if it was added; otherwise this is a no-op. |
164 void RemoveUnresolved(VariableProxy* var); | 167 void RemoveUnresolved(VariableProxy* var); |
165 | 168 |
166 // Creates a new internal variable in this scope. The name is only used | 169 // Creates a new internal variable in this scope. The name is only used |
167 // for printing and cannot be used to find the variable. In particular, | 170 // for printing and cannot be used to find the variable. In particular, |
168 // the only way to get hold of the temporary is by keeping the Variable* | 171 // the only way to get hold of the temporary is by keeping the Variable* |
169 // around. | 172 // around. |
170 Variable* NewInternal(Handle<String> name); | 173 Variable* NewInternal(const AstRawString* name); |
171 | 174 |
172 // Creates a new temporary variable in this scope. The name is only used | 175 // Creates a new temporary variable in this scope. The name is only used |
173 // for printing and cannot be used to find the variable. In particular, | 176 // for printing and cannot be used to find the variable. In particular, |
174 // the only way to get hold of the temporary is by keeping the Variable* | 177 // the only way to get hold of the temporary is by keeping the Variable* |
175 // around. The name should not clash with a legitimate variable names. | 178 // around. The name should not clash with a legitimate variable names. |
176 Variable* NewTemporary(Handle<String> name); | 179 Variable* NewTemporary(const AstRawString* name); |
177 | 180 |
178 // Adds the specific declaration node to the list of declarations in | 181 // Adds the specific declaration node to the list of declarations in |
179 // this scope. The declarations are processed as part of entering | 182 // this scope. The declarations are processed as part of entering |
180 // the scope; see codegen.cc:ProcessDeclarations. | 183 // the scope; see codegen.cc:ProcessDeclarations. |
181 void AddDeclaration(Declaration* declaration); | 184 void AddDeclaration(Declaration* declaration); |
182 | 185 |
183 // --------------------------------------------------------------------------- | 186 // --------------------------------------------------------------------------- |
184 // Illegal redeclaration support. | 187 // Illegal redeclaration support. |
185 | 188 |
186 // Set an expression node that will be executed when the scope is | 189 // Set an expression node that will be executed when the scope is |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 | 386 |
384 // Get the chain of nested scopes within this scope for the source statement | 387 // Get the chain of nested scopes within this scope for the source statement |
385 // position. The scopes will be added to the list from the outermost scope to | 388 // position. The scopes will be added to the list from the outermost scope to |
386 // the innermost scope. Only nested block, catch or with scopes are tracked | 389 // the innermost scope. Only nested block, catch or with scopes are tracked |
387 // and will be returned, but no inner function scopes. | 390 // and will be returned, but no inner function scopes. |
388 void GetNestedScopeChain(List<Handle<ScopeInfo> >* chain, | 391 void GetNestedScopeChain(List<Handle<ScopeInfo> >* chain, |
389 int statement_position); | 392 int statement_position); |
390 | 393 |
391 // --------------------------------------------------------------------------- | 394 // --------------------------------------------------------------------------- |
392 // Strict mode support. | 395 // Strict mode support. |
393 bool IsDeclared(Handle<String> name) { | 396 bool IsDeclared(const AstRawString* name) { |
394 // During formal parameter list parsing the scope only contains | 397 // During formal parameter list parsing the scope only contains |
395 // two variables inserted at initialization: "this" and "arguments". | 398 // two variables inserted at initialization: "this" and "arguments". |
396 // "this" is an invalid parameter name and "arguments" is invalid parameter | 399 // "this" is an invalid parameter name and "arguments" is invalid parameter |
397 // name in strict mode. Therefore looking up with the map which includes | 400 // name in strict mode. Therefore looking up with the map which includes |
398 // "this" and "arguments" in addition to all formal parameters is safe. | 401 // "this" and "arguments" in addition to all formal parameters is safe. |
399 return variables_.Lookup(name) != NULL; | 402 return variables_.Lookup(name) != NULL; |
400 } | 403 } |
401 | 404 |
402 // --------------------------------------------------------------------------- | 405 // --------------------------------------------------------------------------- |
403 // Debugging. | 406 // Debugging. |
(...skipping 10 matching lines...) Expand all Loading... |
414 Isolate* const isolate_; | 417 Isolate* const isolate_; |
415 | 418 |
416 // Scope tree. | 419 // Scope tree. |
417 Scope* outer_scope_; // the immediately enclosing outer scope, or NULL | 420 Scope* outer_scope_; // the immediately enclosing outer scope, or NULL |
418 ZoneList<Scope*> inner_scopes_; // the immediately enclosed inner scopes | 421 ZoneList<Scope*> inner_scopes_; // the immediately enclosed inner scopes |
419 | 422 |
420 // The scope type. | 423 // The scope type. |
421 ScopeType scope_type_; | 424 ScopeType scope_type_; |
422 | 425 |
423 // Debugging support. | 426 // Debugging support. |
424 Handle<String> scope_name_; | 427 const AstRawString* scope_name_; |
425 | 428 |
426 // The variables declared in this scope: | 429 // The variables declared in this scope: |
427 // | 430 // |
428 // All user-declared variables (incl. parameters). For global scopes | 431 // All user-declared variables (incl. parameters). For global scopes |
429 // variables may be implicitly 'declared' by being used (possibly in | 432 // variables may be implicitly 'declared' by being used (possibly in |
430 // an inner scope) with no intervening with statements or eval calls. | 433 // an inner scope) with no intervening with statements or eval calls. |
431 VariableMap variables_; | 434 VariableMap variables_; |
432 // Compiler-allocated (user-invisible) internals. | 435 // Compiler-allocated (user-invisible) internals. |
433 ZoneList<Variable*> internals_; | 436 ZoneList<Variable*> internals_; |
434 // Compiler-allocated (user-invisible) temporaries. | 437 // Compiler-allocated (user-invisible) temporaries. |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 | 493 |
491 // For module scopes, the host scope's internal variable binding this module. | 494 // For module scopes, the host scope's internal variable binding this module. |
492 Variable* module_var_; | 495 Variable* module_var_; |
493 | 496 |
494 // Serialized scope info support. | 497 // Serialized scope info support. |
495 Handle<ScopeInfo> scope_info_; | 498 Handle<ScopeInfo> scope_info_; |
496 bool already_resolved() { return already_resolved_; } | 499 bool already_resolved() { return already_resolved_; } |
497 | 500 |
498 // Create a non-local variable with a given name. | 501 // Create a non-local variable with a given name. |
499 // These variables are looked up dynamically at runtime. | 502 // These variables are looked up dynamically at runtime. |
500 Variable* NonLocal(Handle<String> name, VariableMode mode); | 503 Variable* NonLocal(const AstRawString* name, VariableMode mode); |
501 | 504 |
502 // Variable resolution. | 505 // Variable resolution. |
503 // Possible results of a recursive variable lookup telling if and how a | 506 // Possible results of a recursive variable lookup telling if and how a |
504 // variable is bound. These are returned in the output parameter *binding_kind | 507 // variable is bound. These are returned in the output parameter *binding_kind |
505 // of the LookupRecursive function. | 508 // of the LookupRecursive function. |
506 enum BindingKind { | 509 enum BindingKind { |
507 // The variable reference could be statically resolved to a variable binding | 510 // The variable reference could be statically resolved to a variable binding |
508 // which is returned. There is no 'with' statement between the reference and | 511 // which is returned. There is no 'with' statement between the reference and |
509 // the binding and no scope between the reference scope (inclusive) and | 512 // the binding and no scope between the reference scope (inclusive) and |
510 // binding scope (exclusive) makes a sloppy 'eval' call. | 513 // binding scope (exclusive) makes a sloppy 'eval' call. |
(...skipping 30 matching lines...) Expand all Loading... |
541 // The variable potentially references a property of the 'with' object. | 544 // The variable potentially references a property of the 'with' object. |
542 // * The code is being executed as part of a call to 'eval' and the calling | 545 // * The code is being executed as part of a call to 'eval' and the calling |
543 // context chain contains either a variable binding for the name or it | 546 // context chain contains either a variable binding for the name or it |
544 // contains a 'with' context. | 547 // contains a 'with' context. |
545 DYNAMIC_LOOKUP | 548 DYNAMIC_LOOKUP |
546 }; | 549 }; |
547 | 550 |
548 // Lookup a variable reference given by name recursively starting with this | 551 // Lookup a variable reference given by name recursively starting with this |
549 // scope. If the code is executed because of a call to 'eval', the context | 552 // scope. If the code is executed because of a call to 'eval', the context |
550 // parameter should be set to the calling context of 'eval'. | 553 // parameter should be set to the calling context of 'eval'. |
551 Variable* LookupRecursive(Handle<String> name, | 554 Variable* LookupRecursive(const AstRawString* name, |
552 BindingKind* binding_kind, | 555 BindingKind* binding_kind, |
553 AstNodeFactory<AstNullVisitor>* factory); | 556 AstNodeFactory<AstNullVisitor>* factory); |
554 MUST_USE_RESULT | 557 MUST_USE_RESULT |
555 bool ResolveVariable(CompilationInfo* info, | 558 bool ResolveVariable(CompilationInfo* info, |
556 VariableProxy* proxy, | 559 VariableProxy* proxy, |
557 AstNodeFactory<AstNullVisitor>* factory); | 560 AstNodeFactory<AstNullVisitor>* factory); |
558 MUST_USE_RESULT | 561 MUST_USE_RESULT |
559 bool ResolveVariablesRecursively(CompilationInfo* info, | 562 bool ResolveVariablesRecursively(CompilationInfo* info, |
560 AstNodeFactory<AstNullVisitor>* factory); | 563 AstNodeFactory<AstNullVisitor>* factory); |
561 | 564 |
(...skipping 23 matching lines...) Expand all Loading... |
585 // In the case of code compiled and run using 'eval', the context | 588 // In the case of code compiled and run using 'eval', the context |
586 // parameter is the context in which eval was called. In all other | 589 // parameter is the context in which eval was called. In all other |
587 // cases the context parameter is an empty handle. | 590 // cases the context parameter is an empty handle. |
588 MUST_USE_RESULT | 591 MUST_USE_RESULT |
589 bool AllocateVariables(CompilationInfo* info, | 592 bool AllocateVariables(CompilationInfo* info, |
590 AstNodeFactory<AstNullVisitor>* factory); | 593 AstNodeFactory<AstNullVisitor>* factory); |
591 | 594 |
592 private: | 595 private: |
593 // Construct a scope based on the scope info. | 596 // Construct a scope based on the scope info. |
594 Scope(Scope* inner_scope, ScopeType type, Handle<ScopeInfo> scope_info, | 597 Scope(Scope* inner_scope, ScopeType type, Handle<ScopeInfo> scope_info, |
595 Zone* zone); | 598 AstValueFactory* value_factory, Zone* zone); |
596 | 599 |
597 // Construct a catch scope with a binding for the name. | 600 // Construct a catch scope with a binding for the name. |
598 Scope(Scope* inner_scope, Handle<String> catch_variable_name, Zone* zone); | 601 Scope(Scope* inner_scope, |
| 602 const AstRawString* catch_variable_name, |
| 603 AstValueFactory* value_factory, Zone* zone); |
599 | 604 |
600 void AddInnerScope(Scope* inner_scope) { | 605 void AddInnerScope(Scope* inner_scope) { |
601 if (inner_scope != NULL) { | 606 if (inner_scope != NULL) { |
602 inner_scopes_.Add(inner_scope, zone_); | 607 inner_scopes_.Add(inner_scope, zone_); |
603 inner_scope->outer_scope_ = this; | 608 inner_scope->outer_scope_ = this; |
604 } | 609 } |
605 } | 610 } |
606 | 611 |
607 void SetDefaults(ScopeType type, | 612 void SetDefaults(ScopeType type, |
608 Scope* outer_scope, | 613 Scope* outer_scope, |
609 Handle<ScopeInfo> scope_info); | 614 Handle<ScopeInfo> scope_info); |
610 | 615 |
| 616 AstValueFactory* ast_value_factory_; |
611 Zone* zone_; | 617 Zone* zone_; |
612 }; | 618 }; |
613 | 619 |
614 } } // namespace v8::internal | 620 } } // namespace v8::internal |
615 | 621 |
616 #endif // V8_SCOPES_H_ | 622 #endif // V8_SCOPES_H_ |
OLD | NEW |