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 |