Chromium Code Reviews| 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 "this". | 214 // Inform the scope that the corresponding code uses "this". |
| 215 void RecordThisUsage() { scope_uses_this_ = true; } | 215 void RecordThisUsage() { scope_uses_this_ = true; } |
| 216 | 216 |
| 217 // Inform the scope that the corresponding code uses "arguments". | 217 // Inform the scope that the corresponding code uses "arguments". |
| 218 void RecordArgumentsUsage() { scope_uses_arguments_ = true; } | 218 void RecordArgumentsUsage() { scope_uses_arguments_ = true; } |
| 219 | 219 |
| 220 // Set the strict mode flag (unless disabled by a global flag). | 220 // Set the strict mode flag (unless disabled by a global flag). |
| 221 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; } | 221 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; } |
| 222 | 222 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 265 | 265 |
| 266 // --------------------------------------------------------------------------- | 266 // --------------------------------------------------------------------------- |
| 267 // Predicates. | 267 // Predicates. |
| 268 | 268 |
| 269 // Specific scope types. | 269 // Specific scope types. |
| 270 bool is_eval_scope() const { return scope_type_ == EVAL_SCOPE; } | 270 bool is_eval_scope() const { return scope_type_ == EVAL_SCOPE; } |
| 271 bool is_function_scope() const { | 271 bool is_function_scope() const { |
| 272 return scope_type_ == FUNCTION_SCOPE || scope_type_ == ARROW_SCOPE; | 272 return scope_type_ == FUNCTION_SCOPE || scope_type_ == ARROW_SCOPE; |
| 273 } | 273 } |
| 274 bool is_module_scope() const { return scope_type_ == MODULE_SCOPE; } | 274 bool is_module_scope() const { return scope_type_ == MODULE_SCOPE; } |
| 275 bool is_global_scope() const { return scope_type_ == GLOBAL_SCOPE; } | 275 bool is_script_scope() const { return scope_type_ == SCRIPT_SCOPE; } |
| 276 bool is_catch_scope() const { return scope_type_ == CATCH_SCOPE; } | 276 bool is_catch_scope() const { return scope_type_ == CATCH_SCOPE; } |
| 277 bool is_block_scope() const { return scope_type_ == BLOCK_SCOPE; } | 277 bool is_block_scope() const { return scope_type_ == BLOCK_SCOPE; } |
| 278 bool is_with_scope() const { return scope_type_ == WITH_SCOPE; } | 278 bool is_with_scope() const { return scope_type_ == WITH_SCOPE; } |
| 279 bool is_arrow_scope() const { return scope_type_ == ARROW_SCOPE; } | 279 bool is_arrow_scope() const { return scope_type_ == ARROW_SCOPE; } |
| 280 bool is_declaration_scope() const { | 280 bool is_declaration_scope() const { |
| 281 return is_eval_scope() || is_function_scope() || | 281 return is_eval_scope() || is_function_scope() || |
| 282 is_module_scope() || is_global_scope(); | 282 is_module_scope() || is_script_scope(); |
| 283 } | 283 } |
| 284 bool is_strict_eval_scope() const { | 284 bool is_strict_eval_scope() const { |
| 285 return is_eval_scope() && strict_mode_ == STRICT; | 285 return is_eval_scope() && strict_mode_ == STRICT; |
| 286 } | 286 } |
| 287 | 287 |
| 288 // Information about which scopes calls eval. | 288 // Information about which scopes calls eval. |
| 289 bool calls_eval() const { return scope_calls_eval_; } | 289 bool calls_eval() const { return scope_calls_eval_; } |
| 290 bool calls_sloppy_eval() { | 290 bool calls_sloppy_eval() { |
| 291 return scope_calls_eval_ && strict_mode_ == SLOPPY; | 291 return scope_calls_eval_ && strict_mode_ == SLOPPY; |
| 292 } | 292 } |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 365 // Current number of var or const locals. | 365 // Current number of var or const locals. |
| 366 int num_var_or_const() { return num_var_or_const_; } | 366 int num_var_or_const() { return num_var_or_const_; } |
| 367 | 367 |
| 368 // Result of variable allocation. | 368 // Result of variable allocation. |
| 369 int num_stack_slots() const { return num_stack_slots_; } | 369 int num_stack_slots() const { return num_stack_slots_; } |
| 370 int num_heap_slots() const { return num_heap_slots_; } | 370 int num_heap_slots() const { return num_heap_slots_; } |
| 371 | 371 |
| 372 int StackLocalCount() const; | 372 int StackLocalCount() const; |
| 373 int ContextLocalCount() const; | 373 int ContextLocalCount() const; |
| 374 | 374 |
| 375 // For global scopes, the number of module literals (including nested ones). | 375 // For script scopes, the number of module literals (including nested ones). |
| 376 int num_modules() const { return num_modules_; } | 376 int num_modules() const { return num_modules_; } |
| 377 | 377 |
| 378 // For module scopes, the host scope's internal variable binding this module. | 378 // For module scopes, the host scope's internal variable binding this module. |
| 379 Variable* module_var() const { return module_var_; } | 379 Variable* module_var() const { return module_var_; } |
| 380 | 380 |
| 381 // Make sure this scope and all outer scopes are eagerly compiled. | 381 // Make sure this scope and all outer scopes are eagerly compiled. |
| 382 void ForceEagerCompilation() { force_eager_compilation_ = true; } | 382 void ForceEagerCompilation() { force_eager_compilation_ = true; } |
| 383 | 383 |
| 384 // Determine if we can use lazy compilation for this scope. | 384 // Determine if we can use lazy compilation for this scope. |
| 385 bool AllowsLazyCompilation() const; | 385 bool AllowsLazyCompilation() const; |
| 386 | 386 |
| 387 // Determine if we can use lazy compilation for this scope without a context. | 387 // Determine if we can use lazy compilation for this scope without a context. |
| 388 bool AllowsLazyCompilationWithoutContext() const; | 388 bool AllowsLazyCompilationWithoutContext() const; |
| 389 | 389 |
| 390 // True if the outer context of this scope is always the native context. | 390 // True if the outer context of this scope is always the native context. |
| 391 bool HasTrivialOuterContext() const; | 391 bool HasTrivialOuterContext() const; |
| 392 | 392 |
| 393 // True if the outer context allows lazy compilation of this scope. | 393 // True if the outer context allows lazy compilation of this scope. |
| 394 bool HasLazyCompilableOuterContext() const; | 394 bool HasLazyCompilableOuterContext() const; |
| 395 | 395 |
| 396 // The number of contexts between this and scope; zero if this == scope. | 396 // The number of contexts between this and scope; zero if this == scope. |
| 397 int ContextChainLength(Scope* scope); | 397 int ContextChainLength(Scope* scope); |
| 398 | 398 |
| 399 // Find the innermost global scope. | 399 // Find the innermost script scope. |
|
rossberg
2014/11/12 09:49:27
Nit: remove "innermost". Do we actually still need
Dmitry Lomov (no reviews)
2014/11/12 10:16:27
Done.
It is used in for modules.
| |
| 400 Scope* GlobalScope(); | 400 Scope* ScriptScope(); |
| 401 | 401 |
| 402 // Find the first function, global, or eval scope. This is the scope | 402 // Find the first function, global, or eval scope. This is the scope |
| 403 // where var declarations will be hoisted to in the implementation. | 403 // where var declarations will be hoisted to in the implementation. |
| 404 Scope* DeclarationScope(); | 404 Scope* DeclarationScope(); |
| 405 | 405 |
| 406 Handle<ScopeInfo> GetScopeInfo(); | 406 Handle<ScopeInfo> GetScopeInfo(); |
| 407 | 407 |
| 408 // Get the chain of nested scopes within this scope for the source statement | 408 // Get the chain of nested scopes within this scope for the source statement |
| 409 // position. The scopes will be added to the list from the outermost scope to | 409 // position. The scopes will be added to the list from the outermost scope to |
| 410 // the innermost scope. Only nested block, catch or with scopes are tracked | 410 // 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... | |
| 442 ZoneList<Scope*> inner_scopes_; // the immediately enclosed inner scopes | 442 ZoneList<Scope*> inner_scopes_; // the immediately enclosed inner scopes |
| 443 | 443 |
| 444 // The scope type. | 444 // The scope type. |
| 445 ScopeType scope_type_; | 445 ScopeType scope_type_; |
| 446 | 446 |
| 447 // Debugging support. | 447 // Debugging support. |
| 448 const AstRawString* scope_name_; | 448 const AstRawString* scope_name_; |
| 449 | 449 |
| 450 // The variables declared in this scope: | 450 // The variables declared in this scope: |
| 451 // | 451 // |
| 452 // All user-declared variables (incl. parameters). For global scopes | 452 // All user-declared variables (incl. parameters). For script scopes |
| 453 // variables may be implicitly 'declared' by being used (possibly in | 453 // variables may be implicitly 'declared' by being used (possibly in |
| 454 // an inner scope) with no intervening with statements or eval calls. | 454 // an inner scope) with no intervening with statements or eval calls. |
| 455 VariableMap variables_; | 455 VariableMap variables_; |
| 456 // Compiler-allocated (user-invisible) internals. | 456 // Compiler-allocated (user-invisible) internals. |
| 457 ZoneList<Variable*> internals_; | 457 ZoneList<Variable*> internals_; |
| 458 // Compiler-allocated (user-invisible) temporaries. | 458 // Compiler-allocated (user-invisible) temporaries. |
| 459 ZoneList<Variable*> temps_; | 459 ZoneList<Variable*> temps_; |
| 460 // Parameter list in source order. | 460 // Parameter list in source order. |
| 461 ZoneList<Variable*> params_; | 461 ZoneList<Variable*> params_; |
| 462 // Variables that must be looked up dynamically. | 462 // Variables that must be looked up dynamically. |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 548 // which is returned. There is no 'with' statement between the reference and | 548 // which is returned. There is no 'with' statement between the reference and |
| 549 // the binding, but some scope between the reference scope (inclusive) and | 549 // the binding, but some scope between the reference scope (inclusive) and |
| 550 // binding scope (exclusive) makes a sloppy 'eval' call, that might | 550 // binding scope (exclusive) makes a sloppy 'eval' call, that might |
| 551 // possibly introduce variable bindings shadowing the found one. Thus the | 551 // possibly introduce variable bindings shadowing the found one. Thus the |
| 552 // found variable binding is just a guess. | 552 // found variable binding is just a guess. |
| 553 BOUND_EVAL_SHADOWED, | 553 BOUND_EVAL_SHADOWED, |
| 554 | 554 |
| 555 // The variable reference could not be statically resolved to any binding | 555 // The variable reference could not be statically resolved to any binding |
| 556 // and thus should be considered referencing a global variable. NULL is | 556 // and thus should be considered referencing a global variable. NULL is |
| 557 // returned. The variable reference is not inside any 'with' statement and | 557 // returned. The variable reference is not inside any 'with' statement and |
| 558 // no scope between the reference scope (inclusive) and global scope | 558 // no scope between the reference scope (inclusive) and script scope |
| 559 // (exclusive) makes a sloppy 'eval' call. | 559 // (exclusive) makes a sloppy 'eval' call. |
| 560 UNBOUND, | 560 UNBOUND, |
| 561 | 561 |
| 562 // The variable reference could not be statically resolved to any binding | 562 // The variable reference could not be statically resolved to any binding |
| 563 // NULL is returned. The variable reference is not inside any 'with' | 563 // NULL is returned. The variable reference is not inside any 'with' |
| 564 // statement, but some scope between the reference scope (inclusive) and | 564 // statement, but some scope between the reference scope (inclusive) and |
| 565 // global scope (exclusive) makes a sloppy 'eval' call, that might | 565 // script scope (exclusive) makes a sloppy 'eval' call, that might |
| 566 // possibly introduce a variable binding. Thus the reference should be | 566 // possibly introduce a variable binding. Thus the reference should be |
| 567 // considered referencing a global variable unless it is shadowed by an | 567 // considered referencing a global variable unless it is shadowed by an |
| 568 // 'eval' introduced binding. | 568 // 'eval' introduced binding. |
| 569 UNBOUND_EVAL_SHADOWED, | 569 UNBOUND_EVAL_SHADOWED, |
| 570 | 570 |
| 571 // The variable could not be statically resolved and needs to be looked up | 571 // The variable could not be statically resolved and needs to be looked up |
| 572 // dynamically. NULL is returned. There are two possible reasons: | 572 // dynamically. NULL is returned. There are two possible reasons: |
| 573 // * A 'with' statement has been encountered and there is no variable | 573 // * A 'with' statement has been encountered and there is no variable |
| 574 // binding for the name between the variable reference and the 'with'. | 574 // binding for the name between the variable reference and the 'with'. |
| 575 // The variable potentially references a property of the 'with' object. | 575 // The variable potentially references a property of the 'with' object. |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 644 Scope* outer_scope, | 644 Scope* outer_scope, |
| 645 Handle<ScopeInfo> scope_info); | 645 Handle<ScopeInfo> scope_info); |
| 646 | 646 |
| 647 AstValueFactory* ast_value_factory_; | 647 AstValueFactory* ast_value_factory_; |
| 648 Zone* zone_; | 648 Zone* zone_; |
| 649 }; | 649 }; |
| 650 | 650 |
| 651 } } // namespace v8::internal | 651 } } // namespace v8::internal |
| 652 | 652 |
| 653 #endif // V8_SCOPES_H_ | 653 #endif // V8_SCOPES_H_ |
| OLD | NEW |