| 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 #include "src/ast/scopes.h" | 5 #include "src/ast/scopes.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
| 10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
| (...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 | 392 |
| 393 const ModuleScope* Scope::AsModuleScope() const { | 393 const ModuleScope* Scope::AsModuleScope() const { |
| 394 DCHECK(is_module_scope()); | 394 DCHECK(is_module_scope()); |
| 395 return static_cast<const ModuleScope*>(this); | 395 return static_cast<const ModuleScope*>(this); |
| 396 } | 396 } |
| 397 | 397 |
| 398 int Scope::num_parameters() const { | 398 int Scope::num_parameters() const { |
| 399 return is_declaration_scope() ? AsDeclarationScope()->num_parameters() : 0; | 399 return is_declaration_scope() ? AsDeclarationScope()->num_parameters() : 0; |
| 400 } | 400 } |
| 401 | 401 |
| 402 void Scope::Analyze(ParseInfo* info) { | 402 void DeclarationScope::Analyze(ParseInfo* info) { |
| 403 DCHECK(info->literal() != NULL); | 403 DCHECK(info->literal() != NULL); |
| 404 DeclarationScope* scope = info->literal()->scope(); | 404 DeclarationScope* scope = info->literal()->scope(); |
| 405 | 405 |
| 406 // We are compiling one of three cases: | 406 // We are compiling one of three cases: |
| 407 // 1) top-level code, | 407 // 1) top-level code, |
| 408 // 2) a function/eval/module on the top-level | 408 // 2) a function/eval/module on the top-level |
| 409 // 3) a function/eval in a scope that was already resolved. | 409 // 3) a function/eval in a scope that was already resolved. |
| 410 DCHECK(scope->scope_type() == SCRIPT_SCOPE || | 410 DCHECK(scope->scope_type() == SCRIPT_SCOPE || |
| 411 scope->outer_scope()->scope_type() == SCRIPT_SCOPE || | 411 scope->outer_scope()->scope_type() == SCRIPT_SCOPE || |
| 412 scope->outer_scope()->already_resolved_); | 412 scope->outer_scope()->already_resolved_); |
| 413 | 413 |
| 414 scope->AllocateVariables(info); | 414 scope->AllocateVariables(info, false /* for_debugger */); |
| 415 | 415 |
| 416 #ifdef DEBUG | 416 #ifdef DEBUG |
| 417 if (info->script_is_native() ? FLAG_print_builtin_scopes | 417 if (info->script_is_native() ? FLAG_print_builtin_scopes |
| 418 : FLAG_print_scopes) { | 418 : FLAG_print_scopes) { |
| 419 scope->Print(); | 419 scope->Print(); |
| 420 } | 420 } |
| 421 scope->CheckScopePositions(); | 421 scope->CheckScopePositions(); |
| 422 scope->CheckZones(); | 422 scope->CheckZones(); |
| 423 #endif | 423 #endif |
| 424 } | 424 } |
| 425 | 425 |
| 426 void DeclarationScope::AnalyzeForDebugger(ParseInfo* info) { |
| 427 DCHECK(info->literal() != NULL); |
| 428 DeclarationScope* scope = info->literal()->scope(); |
| 429 |
| 430 // We are compiling one of three cases: |
| 431 // 1) top-level code, |
| 432 // 2) a function/eval/module on the top-level |
| 433 // 3) a function/eval in a scope that was already resolved. |
| 434 DCHECK(scope->scope_type() == SCRIPT_SCOPE || |
| 435 scope->outer_scope()->scope_type() == SCRIPT_SCOPE || |
| 436 scope->outer_scope()->already_resolved_); |
| 437 |
| 438 scope->AllocateVariables(info, true /* for_debugger */); |
| 439 } |
| 440 |
| 426 void DeclarationScope::DeclareThis(AstValueFactory* ast_value_factory) { | 441 void DeclarationScope::DeclareThis(AstValueFactory* ast_value_factory) { |
| 427 DCHECK(!already_resolved_); | 442 DCHECK(!already_resolved_); |
| 428 DCHECK(is_declaration_scope()); | 443 DCHECK(is_declaration_scope()); |
| 429 DCHECK(has_this_declaration()); | 444 DCHECK(has_this_declaration()); |
| 430 | 445 |
| 431 bool subclass_constructor = IsSubclassConstructor(function_kind_); | 446 bool subclass_constructor = IsSubclassConstructor(function_kind_); |
| 432 Variable* var = Declare( | 447 Variable* var = Declare( |
| 433 zone(), this, ast_value_factory->this_string(), | 448 zone(), this, ast_value_factory->this_string(), |
| 434 subclass_constructor ? CONST : VAR, Variable::THIS, | 449 subclass_constructor ? CONST : VAR, Variable::THIS, |
| 435 subclass_constructor ? kNeedsInitialization : kCreatedInitialized); | 450 subclass_constructor ? kNeedsInitialization : kCreatedInitialized); |
| (...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 870 if (decls_[j]->proxy()->raw_name() == name) { | 885 if (decls_[j]->proxy()->raw_name() == name) { |
| 871 return decls_[j]; | 886 return decls_[j]; |
| 872 } | 887 } |
| 873 } | 888 } |
| 874 DCHECK(false); | 889 DCHECK(false); |
| 875 } | 890 } |
| 876 } | 891 } |
| 877 return nullptr; | 892 return nullptr; |
| 878 } | 893 } |
| 879 | 894 |
| 880 void DeclarationScope::AllocateVariables(ParseInfo* info) { | 895 void DeclarationScope::AllocateVariables(ParseInfo* info, bool for_debugger) { |
| 881 // 1) Propagate scope information. | |
| 882 PropagateScopeInfo(); | 896 PropagateScopeInfo(); |
| 883 | |
| 884 // 2) Resolve variables. | |
| 885 ResolveVariablesRecursively(info); | 897 ResolveVariablesRecursively(info); |
| 886 | |
| 887 // 3) Allocate variables. | |
| 888 AllocateVariablesRecursively(); | 898 AllocateVariablesRecursively(); |
| 899 AllocateScopeInfosRecursively(info->isolate(), for_debugger); |
| 889 } | 900 } |
| 890 | 901 |
| 891 | |
| 892 bool Scope::AllowsLazyParsing() const { | 902 bool Scope::AllowsLazyParsing() const { |
| 893 // If we are inside a block scope, we must parse eagerly to find out how | 903 // If we are inside a block scope, we must parse eagerly to find out how |
| 894 // to allocate variables on the block scope. At this point, declarations may | 904 // to allocate variables on the block scope. At this point, declarations may |
| 895 // not have yet been parsed. | 905 // not have yet been parsed. |
| 896 for (const Scope* s = this; s != nullptr; s = s->outer_scope_) { | 906 for (const Scope* s = this; s != nullptr; s = s->outer_scope_) { |
| 897 if (s->is_block_scope()) return false; | 907 if (s->is_block_scope()) return false; |
| 898 } | 908 } |
| 899 return true; | 909 return true; |
| 900 } | 910 } |
| 901 | 911 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 967 DeclarationScope* Scope::GetReceiverScope() { | 977 DeclarationScope* Scope::GetReceiverScope() { |
| 968 Scope* scope = this; | 978 Scope* scope = this; |
| 969 while (!scope->is_script_scope() && | 979 while (!scope->is_script_scope() && |
| 970 (!scope->is_function_scope() || | 980 (!scope->is_function_scope() || |
| 971 scope->AsDeclarationScope()->is_arrow_scope())) { | 981 scope->AsDeclarationScope()->is_arrow_scope())) { |
| 972 scope = scope->outer_scope(); | 982 scope = scope->outer_scope(); |
| 973 } | 983 } |
| 974 return scope->AsDeclarationScope(); | 984 return scope->AsDeclarationScope(); |
| 975 } | 985 } |
| 976 | 986 |
| 977 | |
| 978 | |
| 979 Handle<ScopeInfo> Scope::GetScopeInfo(Isolate* isolate) { | |
| 980 if (scope_info_.is_null()) { | |
| 981 scope_info_ = ScopeInfo::Create(isolate, zone(), this); | |
| 982 } | |
| 983 return scope_info_; | |
| 984 } | |
| 985 | |
| 986 Handle<StringSet> DeclarationScope::CollectNonLocals( | 987 Handle<StringSet> DeclarationScope::CollectNonLocals( |
| 987 ParseInfo* info, Handle<StringSet> non_locals) { | 988 ParseInfo* info, Handle<StringSet> non_locals) { |
| 988 VariableProxy* free_variables = FetchFreeVariables(this, info); | 989 VariableProxy* free_variables = FetchFreeVariables(this, info); |
| 989 for (VariableProxy* proxy = free_variables; proxy != nullptr; | 990 for (VariableProxy* proxy = free_variables; proxy != nullptr; |
| 990 proxy = proxy->next_unresolved()) { | 991 proxy = proxy->next_unresolved()) { |
| 991 non_locals = StringSet::Add(non_locals, proxy->name()); | 992 non_locals = StringSet::Add(non_locals, proxy->name()); |
| 992 } | 993 } |
| 993 return non_locals; | 994 return non_locals; |
| 994 } | 995 } |
| 995 | 996 |
| (...skipping 639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1635 // If we didn't allocate any locals in the local context, then we only | 1636 // If we didn't allocate any locals in the local context, then we only |
| 1636 // need the minimal number of slots if we must have a context. | 1637 // need the minimal number of slots if we must have a context. |
| 1637 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) { | 1638 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) { |
| 1638 num_heap_slots_ = 0; | 1639 num_heap_slots_ = 0; |
| 1639 } | 1640 } |
| 1640 | 1641 |
| 1641 // Allocation done. | 1642 // Allocation done. |
| 1642 DCHECK(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); | 1643 DCHECK(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); |
| 1643 } | 1644 } |
| 1644 | 1645 |
| 1646 void Scope::AllocateScopeInfosRecursively(Isolate* isolate, bool for_debugger) { |
| 1647 DCHECK(scope_info_.is_null()); |
| 1648 if (for_debugger || NeedsScopeInfo()) { |
| 1649 scope_info_ = ScopeInfo::Create(isolate, zone(), this); |
| 1650 } |
| 1651 |
| 1652 // Allocate ScopeInfos for inner scopes. |
| 1653 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
| 1654 scope->AllocateScopeInfosRecursively(isolate, for_debugger); |
| 1655 } |
| 1656 } |
| 1645 | 1657 |
| 1646 int Scope::StackLocalCount() const { | 1658 int Scope::StackLocalCount() const { |
| 1647 Variable* function = | 1659 Variable* function = |
| 1648 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; | 1660 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; |
| 1649 return num_stack_slots() - | 1661 return num_stack_slots() - |
| 1650 (function != nullptr && function->IsStackLocal() ? 1 : 0); | 1662 (function != nullptr && function->IsStackLocal() ? 1 : 0); |
| 1651 } | 1663 } |
| 1652 | 1664 |
| 1653 | 1665 |
| 1654 int Scope::ContextLocalCount() const { | 1666 int Scope::ContextLocalCount() const { |
| 1655 if (num_heap_slots() == 0) return 0; | 1667 if (num_heap_slots() == 0) return 0; |
| 1656 Variable* function = | 1668 Variable* function = |
| 1657 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; | 1669 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; |
| 1658 bool is_function_var_in_context = | 1670 bool is_function_var_in_context = |
| 1659 function != nullptr && function->IsContextSlot(); | 1671 function != nullptr && function->IsContextSlot(); |
| 1660 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 1672 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
| 1661 (is_function_var_in_context ? 1 : 0); | 1673 (is_function_var_in_context ? 1 : 0); |
| 1662 } | 1674 } |
| 1663 | 1675 |
| 1664 } // namespace internal | 1676 } // namespace internal |
| 1665 } // namespace v8 | 1677 } // namespace v8 |
| OLD | NEW |