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 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 // Construction | 73 // Construction |
74 | 74 |
75 Scope(Scope* outer_scope, ScopeType scope_type, | 75 Scope(Scope* outer_scope, ScopeType scope_type, |
76 AstValueFactory* value_factory, Zone* zone); | 76 AstValueFactory* value_factory, Zone* zone); |
77 | 77 |
78 // Compute top scope and allocate variables. For lazy compilation the top | 78 // Compute top scope and allocate variables. For lazy compilation the top |
79 // scope only contains the single lazily compiled function, so this | 79 // scope only contains the single lazily compiled function, so this |
80 // doesn't re-allocate variables repeatedly. | 80 // doesn't re-allocate variables repeatedly. |
81 static bool Analyze(CompilationInfo* info); | 81 static bool Analyze(CompilationInfo* info); |
82 | 82 |
83 static Scope* DeserializeScopeChain(Context* context, Scope* global_scope, | 83 static Scope* DeserializeScopeChain(Context* context, Scope* script_scope, |
84 Zone* zone); | 84 Zone* zone); |
85 | 85 |
86 // The scope name is only used for printing/debugging. | 86 // The scope name is only used for printing/debugging. |
87 void SetScopeName(const AstRawString* scope_name) { | 87 void SetScopeName(const AstRawString* scope_name) { |
88 scope_name_ = scope_name; | 88 scope_name_ = scope_name; |
89 } | 89 } |
90 | 90 |
91 void Initialize(); | 91 void Initialize(); |
92 | 92 |
93 // Checks if the block scope is redundant, i.e. it does not contain any | 93 // Checks if the block scope is redundant, i.e. it does not contain any |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 Variable* DeclareParameter(const AstRawString* name, VariableMode mode); | 128 Variable* DeclareParameter(const AstRawString* name, VariableMode mode); |
129 | 129 |
130 // Declare a local variable in this scope. If the variable has been | 130 // Declare a local variable in this scope. If the variable has been |
131 // declared before, the previously declared variable is returned. | 131 // declared before, the previously declared variable is returned. |
132 Variable* DeclareLocal(const AstRawString* name, VariableMode mode, | 132 Variable* DeclareLocal(const AstRawString* name, VariableMode mode, |
133 InitializationFlag init_flag, | 133 InitializationFlag init_flag, |
134 MaybeAssignedFlag maybe_assigned_flag = kNotAssigned, | 134 MaybeAssignedFlag maybe_assigned_flag = kNotAssigned, |
135 Interface* interface = Interface::NewValue()); | 135 Interface* interface = Interface::NewValue()); |
136 | 136 |
137 // Declare an implicit global variable in this scope which must be a | 137 // Declare an implicit global variable in this scope which must be a |
138 // global scope. The variable was introduced (possibly from an inner | 138 // script scope. The variable was introduced (possibly from an inner |
139 // scope) by a reference to an unresolved variable with no intervening | 139 // scope) by a reference to an unresolved variable with no intervening |
140 // with statements or eval calls. | 140 // with statements or eval calls. |
141 Variable* DeclareDynamicGlobal(const AstRawString* name); | 141 Variable* DeclareDynamicGlobal(const AstRawString* name); |
142 | 142 |
143 // Create a new unresolved variable. | 143 // Create a new unresolved variable. |
144 template<class Visitor> | 144 template<class Visitor> |
145 VariableProxy* NewUnresolved(AstNodeFactory<Visitor>* factory, | 145 VariableProxy* NewUnresolved(AstNodeFactory<Visitor>* factory, |
146 const AstRawString* name, | 146 const AstRawString* name, |
147 Interface* interface = Interface::NewValue(), | 147 Interface* interface = Interface::NewValue(), |
148 int position = RelocInfo::kNoPosition) { | 148 int position = RelocInfo::kNoPosition) { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 // scope over a let binding of the same name. | 202 // scope over a let binding of the same name. |
203 Declaration* CheckConflictingVarDeclarations(); | 203 Declaration* CheckConflictingVarDeclarations(); |
204 | 204 |
205 // --------------------------------------------------------------------------- | 205 // --------------------------------------------------------------------------- |
206 // Scope-specific info. | 206 // Scope-specific info. |
207 | 207 |
208 // Inform the scope that the corresponding code contains a with statement. | 208 // Inform the scope that the corresponding code contains a with statement. |
209 void RecordWithStatement() { scope_contains_with_ = true; } | 209 void RecordWithStatement() { scope_contains_with_ = true; } |
210 | 210 |
211 // Inform the scope that the corresponding code contains an eval call. | 211 // Inform the scope that the corresponding code contains an eval call. |
212 void RecordEvalCall() { if (!is_global_scope()) scope_calls_eval_ = true; } | 212 void RecordEvalCall() { if (!is_script_scope()) scope_calls_eval_ = true; } |
213 | 213 |
214 // Inform the scope that the corresponding code uses "arguments". | 214 // Inform the scope that the corresponding code uses "arguments". |
215 void RecordArgumentsUsage() { scope_uses_arguments_ = true; } | 215 void RecordArgumentsUsage() { scope_uses_arguments_ = true; } |
216 | 216 |
217 // Inform the scope that the corresponding code uses "super". | 217 // Inform the scope that the corresponding code uses "super". |
218 void RecordSuperUsage() { scope_uses_super_ = true; } | 218 void RecordSuperUsage() { scope_uses_super_ = true; } |
219 | 219 |
220 // Inform the scope that the corresponding code uses "this". | 220 // Inform the scope that the corresponding code uses "this". |
221 void RecordThisUsage() { scope_uses_this_ = true; } | 221 void RecordThisUsage() { scope_uses_this_ = true; } |
222 | 222 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 | 268 |
269 // --------------------------------------------------------------------------- | 269 // --------------------------------------------------------------------------- |
270 // Predicates. | 270 // Predicates. |
271 | 271 |
272 // Specific scope types. | 272 // Specific scope types. |
273 bool is_eval_scope() const { return scope_type_ == EVAL_SCOPE; } | 273 bool is_eval_scope() const { return scope_type_ == EVAL_SCOPE; } |
274 bool is_function_scope() const { | 274 bool is_function_scope() const { |
275 return scope_type_ == FUNCTION_SCOPE || scope_type_ == ARROW_SCOPE; | 275 return scope_type_ == FUNCTION_SCOPE || scope_type_ == ARROW_SCOPE; |
276 } | 276 } |
277 bool is_module_scope() const { return scope_type_ == MODULE_SCOPE; } | 277 bool is_module_scope() const { return scope_type_ == MODULE_SCOPE; } |
278 bool is_global_scope() const { return scope_type_ == GLOBAL_SCOPE; } | 278 bool is_script_scope() const { return scope_type_ == SCRIPT_SCOPE; } |
279 bool is_catch_scope() const { return scope_type_ == CATCH_SCOPE; } | 279 bool is_catch_scope() const { return scope_type_ == CATCH_SCOPE; } |
280 bool is_block_scope() const { return scope_type_ == BLOCK_SCOPE; } | 280 bool is_block_scope() const { return scope_type_ == BLOCK_SCOPE; } |
281 bool is_with_scope() const { return scope_type_ == WITH_SCOPE; } | 281 bool is_with_scope() const { return scope_type_ == WITH_SCOPE; } |
282 bool is_arrow_scope() const { return scope_type_ == ARROW_SCOPE; } | 282 bool is_arrow_scope() const { return scope_type_ == ARROW_SCOPE; } |
283 bool is_declaration_scope() const { | 283 bool is_declaration_scope() const { |
284 return is_eval_scope() || is_function_scope() || | 284 return is_eval_scope() || is_function_scope() || |
285 is_module_scope() || is_global_scope(); | 285 is_module_scope() || is_script_scope(); |
286 } | 286 } |
287 bool is_strict_eval_scope() const { | 287 bool is_strict_eval_scope() const { |
288 return is_eval_scope() && strict_mode_ == STRICT; | 288 return is_eval_scope() && strict_mode_ == STRICT; |
289 } | 289 } |
290 | 290 |
291 // Information about which scopes calls eval. | 291 // Information about which scopes calls eval. |
292 bool calls_eval() const { return scope_calls_eval_; } | 292 bool calls_eval() const { return scope_calls_eval_; } |
293 bool calls_sloppy_eval() { | 293 bool calls_sloppy_eval() { |
294 return scope_calls_eval_ && strict_mode_ == SLOPPY; | 294 return scope_calls_eval_ && strict_mode_ == SLOPPY; |
295 } | 295 } |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 // Current number of var or const locals. | 372 // Current number of var or const locals. |
373 int num_var_or_const() { return num_var_or_const_; } | 373 int num_var_or_const() { return num_var_or_const_; } |
374 | 374 |
375 // Result of variable allocation. | 375 // Result of variable allocation. |
376 int num_stack_slots() const { return num_stack_slots_; } | 376 int num_stack_slots() const { return num_stack_slots_; } |
377 int num_heap_slots() const { return num_heap_slots_; } | 377 int num_heap_slots() const { return num_heap_slots_; } |
378 | 378 |
379 int StackLocalCount() const; | 379 int StackLocalCount() const; |
380 int ContextLocalCount() const; | 380 int ContextLocalCount() const; |
381 | 381 |
382 // For global scopes, the number of module literals (including nested ones). | 382 // For script scopes, the number of module literals (including nested ones). |
383 int num_modules() const { return num_modules_; } | 383 int num_modules() const { return num_modules_; } |
384 | 384 |
385 // For module scopes, the host scope's internal variable binding this module. | 385 // For module scopes, the host scope's internal variable binding this module. |
386 Variable* module_var() const { return module_var_; } | 386 Variable* module_var() const { return module_var_; } |
387 | 387 |
388 // Make sure this scope and all outer scopes are eagerly compiled. | 388 // Make sure this scope and all outer scopes are eagerly compiled. |
389 void ForceEagerCompilation() { force_eager_compilation_ = true; } | 389 void ForceEagerCompilation() { force_eager_compilation_ = true; } |
390 | 390 |
391 // Determine if we can use lazy compilation for this scope. | 391 // Determine if we can use lazy compilation for this scope. |
392 bool AllowsLazyCompilation() const; | 392 bool AllowsLazyCompilation() const; |
393 | 393 |
394 // Determine if we can use lazy compilation for this scope without a context. | 394 // Determine if we can use lazy compilation for this scope without a context. |
395 bool AllowsLazyCompilationWithoutContext() const; | 395 bool AllowsLazyCompilationWithoutContext() const; |
396 | 396 |
397 // True if the outer context of this scope is always the native context. | 397 // True if the outer context of this scope is always the native context. |
398 bool HasTrivialOuterContext() const; | 398 bool HasTrivialOuterContext() const; |
399 | 399 |
400 // True if the outer context allows lazy compilation of this scope. | 400 // True if the outer context allows lazy compilation of this scope. |
401 bool HasLazyCompilableOuterContext() const; | 401 bool HasLazyCompilableOuterContext() const; |
402 | 402 |
403 // The number of contexts between this and scope; zero if this == scope. | 403 // The number of contexts between this and scope; zero if this == scope. |
404 int ContextChainLength(Scope* scope); | 404 int ContextChainLength(Scope* scope); |
405 | 405 |
406 // Find the innermost global scope. | 406 // Find the script scope. |
407 Scope* GlobalScope(); | 407 // Used in modules implemenetation to find hosting scope. |
| 408 // TODO(rossberg): is this needed? |
| 409 Scope* ScriptScope(); |
408 | 410 |
409 // Find the first function, global, or eval scope. This is the scope | 411 // Find the first function, global, or eval scope. This is the scope |
410 // where var declarations will be hoisted to in the implementation. | 412 // where var declarations will be hoisted to in the implementation. |
411 Scope* DeclarationScope(); | 413 Scope* DeclarationScope(); |
412 | 414 |
413 Handle<ScopeInfo> GetScopeInfo(); | 415 Handle<ScopeInfo> GetScopeInfo(); |
414 | 416 |
415 // Get the chain of nested scopes within this scope for the source statement | 417 // Get the chain of nested scopes within this scope for the source statement |
416 // position. The scopes will be added to the list from the outermost scope to | 418 // position. The scopes will be added to the list from the outermost scope to |
417 // the innermost scope. Only nested block, catch or with scopes are tracked | 419 // the innermost scope. Only nested block, catch or with scopes are tracked |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 ZoneList<Scope*> inner_scopes_; // the immediately enclosed inner scopes | 451 ZoneList<Scope*> inner_scopes_; // the immediately enclosed inner scopes |
450 | 452 |
451 // The scope type. | 453 // The scope type. |
452 ScopeType scope_type_; | 454 ScopeType scope_type_; |
453 | 455 |
454 // Debugging support. | 456 // Debugging support. |
455 const AstRawString* scope_name_; | 457 const AstRawString* scope_name_; |
456 | 458 |
457 // The variables declared in this scope: | 459 // The variables declared in this scope: |
458 // | 460 // |
459 // All user-declared variables (incl. parameters). For global scopes | 461 // All user-declared variables (incl. parameters). For script scopes |
460 // variables may be implicitly 'declared' by being used (possibly in | 462 // variables may be implicitly 'declared' by being used (possibly in |
461 // an inner scope) with no intervening with statements or eval calls. | 463 // an inner scope) with no intervening with statements or eval calls. |
462 VariableMap variables_; | 464 VariableMap variables_; |
463 // Compiler-allocated (user-invisible) internals. | 465 // Compiler-allocated (user-invisible) internals. |
464 ZoneList<Variable*> internals_; | 466 ZoneList<Variable*> internals_; |
465 // Compiler-allocated (user-invisible) temporaries. | 467 // Compiler-allocated (user-invisible) temporaries. |
466 ZoneList<Variable*> temps_; | 468 ZoneList<Variable*> temps_; |
467 // Parameter list in source order. | 469 // Parameter list in source order. |
468 ZoneList<Variable*> params_; | 470 ZoneList<Variable*> params_; |
469 // Variables that must be looked up dynamically. | 471 // Variables that must be looked up dynamically. |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
558 // which is returned. There is no 'with' statement between the reference and | 560 // which is returned. There is no 'with' statement between the reference and |
559 // the binding, but some scope between the reference scope (inclusive) and | 561 // the binding, but some scope between the reference scope (inclusive) and |
560 // binding scope (exclusive) makes a sloppy 'eval' call, that might | 562 // binding scope (exclusive) makes a sloppy 'eval' call, that might |
561 // possibly introduce variable bindings shadowing the found one. Thus the | 563 // possibly introduce variable bindings shadowing the found one. Thus the |
562 // found variable binding is just a guess. | 564 // found variable binding is just a guess. |
563 BOUND_EVAL_SHADOWED, | 565 BOUND_EVAL_SHADOWED, |
564 | 566 |
565 // The variable reference could not be statically resolved to any binding | 567 // The variable reference could not be statically resolved to any binding |
566 // and thus should be considered referencing a global variable. NULL is | 568 // and thus should be considered referencing a global variable. NULL is |
567 // returned. The variable reference is not inside any 'with' statement and | 569 // returned. The variable reference is not inside any 'with' statement and |
568 // no scope between the reference scope (inclusive) and global scope | 570 // no scope between the reference scope (inclusive) and script scope |
569 // (exclusive) makes a sloppy 'eval' call. | 571 // (exclusive) makes a sloppy 'eval' call. |
570 UNBOUND, | 572 UNBOUND, |
571 | 573 |
572 // The variable reference could not be statically resolved to any binding | 574 // The variable reference could not be statically resolved to any binding |
573 // NULL is returned. The variable reference is not inside any 'with' | 575 // NULL is returned. The variable reference is not inside any 'with' |
574 // statement, but some scope between the reference scope (inclusive) and | 576 // statement, but some scope between the reference scope (inclusive) and |
575 // global scope (exclusive) makes a sloppy 'eval' call, that might | 577 // script scope (exclusive) makes a sloppy 'eval' call, that might |
576 // possibly introduce a variable binding. Thus the reference should be | 578 // possibly introduce a variable binding. Thus the reference should be |
577 // considered referencing a global variable unless it is shadowed by an | 579 // considered referencing a global variable unless it is shadowed by an |
578 // 'eval' introduced binding. | 580 // 'eval' introduced binding. |
579 UNBOUND_EVAL_SHADOWED, | 581 UNBOUND_EVAL_SHADOWED, |
580 | 582 |
581 // The variable could not be statically resolved and needs to be looked up | 583 // The variable could not be statically resolved and needs to be looked up |
582 // dynamically. NULL is returned. There are two possible reasons: | 584 // dynamically. NULL is returned. There are two possible reasons: |
583 // * A 'with' statement has been encountered and there is no variable | 585 // * A 'with' statement has been encountered and there is no variable |
584 // binding for the name between the variable reference and the 'with'. | 586 // binding for the name between the variable reference and the 'with'. |
585 // The variable potentially references a property of the 'with' object. | 587 // The variable potentially references a property of the 'with' object. |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
654 Scope* outer_scope, | 656 Scope* outer_scope, |
655 Handle<ScopeInfo> scope_info); | 657 Handle<ScopeInfo> scope_info); |
656 | 658 |
657 AstValueFactory* ast_value_factory_; | 659 AstValueFactory* ast_value_factory_; |
658 Zone* zone_; | 660 Zone* zone_; |
659 }; | 661 }; |
660 | 662 |
661 } } // namespace v8::internal | 663 } } // namespace v8::internal |
662 | 664 |
663 #endif // V8_SCOPES_H_ | 665 #endif // V8_SCOPES_H_ |
OLD | NEW |