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 834 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
845 } | 845 } |
846 | 846 |
847 void DeclarationScope::AllocateVariables(ParseInfo* info) { | 847 void DeclarationScope::AllocateVariables(ParseInfo* info) { |
848 // 1) Propagate scope information. | 848 // 1) Propagate scope information. |
849 PropagateScopeInfo(); | 849 PropagateScopeInfo(); |
850 | 850 |
851 // 2) Resolve variables. | 851 // 2) Resolve variables. |
852 ResolveVariablesRecursively(info); | 852 ResolveVariablesRecursively(info); |
853 | 853 |
854 // 3) Allocate variables. | 854 // 3) Allocate variables. |
855 AllocateVariablesRecursively(); | 855 AllocateVariablesRecursively(info->isolate()); |
856 } | 856 } |
857 | 857 |
858 | 858 |
859 bool Scope::AllowsLazyParsing() const { | 859 bool Scope::AllowsLazyParsing() const { |
860 // If we are inside a block scope, we must parse eagerly to find out how | 860 // If we are inside a block scope, we must parse eagerly to find out how |
861 // to allocate variables on the block scope. At this point, declarations may | 861 // to allocate variables on the block scope. At this point, declarations may |
862 // not have yet been parsed. | 862 // not have yet been parsed. |
863 for (const Scope* s = this; s != nullptr; s = s->outer_scope_) { | 863 for (const Scope* s = this; s != nullptr; s = s->outer_scope_) { |
864 if (s->is_block_scope()) return false; | 864 if (s->is_block_scope()) return false; |
865 } | 865 } |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
934 DeclarationScope* Scope::GetReceiverScope() { | 934 DeclarationScope* Scope::GetReceiverScope() { |
935 Scope* scope = this; | 935 Scope* scope = this; |
936 while (!scope->is_script_scope() && | 936 while (!scope->is_script_scope() && |
937 (!scope->is_function_scope() || | 937 (!scope->is_function_scope() || |
938 scope->AsDeclarationScope()->is_arrow_scope())) { | 938 scope->AsDeclarationScope()->is_arrow_scope())) { |
939 scope = scope->outer_scope(); | 939 scope = scope->outer_scope(); |
940 } | 940 } |
941 return scope->AsDeclarationScope(); | 941 return scope->AsDeclarationScope(); |
942 } | 942 } |
943 | 943 |
944 | |
945 | |
946 Handle<ScopeInfo> Scope::GetScopeInfo(Isolate* isolate) { | |
947 if (scope_info_.is_null()) { | |
948 scope_info_ = ScopeInfo::Create(isolate, zone(), this); | |
949 } | |
950 return scope_info_; | |
951 } | |
952 | |
953 Handle<StringSet> DeclarationScope::CollectNonLocals( | 944 Handle<StringSet> DeclarationScope::CollectNonLocals( |
954 ParseInfo* info, Handle<StringSet> non_locals) { | 945 ParseInfo* info, Handle<StringSet> non_locals) { |
955 VariableProxy* free_variables = FetchFreeVariables(this, info); | 946 VariableProxy* free_variables = FetchFreeVariables(this, info); |
956 for (VariableProxy* proxy = free_variables; proxy != nullptr; | 947 for (VariableProxy* proxy = free_variables; proxy != nullptr; |
957 proxy = proxy->next_unresolved()) { | 948 proxy = proxy->next_unresolved()) { |
958 non_locals = StringSet::Add(non_locals, proxy->name()); | 949 non_locals = StringSet::Add(non_locals, proxy->name()); |
959 } | 950 } |
960 return non_locals; | 951 return non_locals; |
961 } | 952 } |
962 | 953 |
(...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1583 // TODO(neis): Use a meaningful index. | 1574 // TODO(neis): Use a meaningful index. |
1584 var->AllocateTo(VariableLocation::MODULE, 42); | 1575 var->AllocateTo(VariableLocation::MODULE, 42); |
1585 } | 1576 } |
1586 | 1577 |
1587 for (const auto& it : module()->regular_exports()) { | 1578 for (const auto& it : module()->regular_exports()) { |
1588 Variable* var = LookupLocal(it.first); | 1579 Variable* var = LookupLocal(it.first); |
1589 var->AllocateTo(VariableLocation::MODULE, 0); | 1580 var->AllocateTo(VariableLocation::MODULE, 0); |
1590 } | 1581 } |
1591 } | 1582 } |
1592 | 1583 |
1593 void Scope::AllocateVariablesRecursively() { | 1584 void Scope::AllocateVariablesRecursively(Isolate* isolate) { |
1594 DCHECK(!already_resolved_); | 1585 DCHECK(!already_resolved_); |
1595 DCHECK_EQ(0, num_stack_slots_); | 1586 DCHECK_EQ(0, num_stack_slots_); |
1596 | |
1597 // Allocate variables for inner scopes. | |
1598 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | |
1599 scope->AllocateVariablesRecursively(); | |
1600 } | |
1601 | |
1602 DCHECK(!already_resolved_); | 1587 DCHECK(!already_resolved_); |
1603 DCHECK_EQ(Context::MIN_CONTEXT_SLOTS, num_heap_slots_); | 1588 DCHECK_EQ(Context::MIN_CONTEXT_SLOTS, num_heap_slots_); |
1604 | 1589 |
1605 // Allocate variables for this scope. | 1590 // Allocate variables for this scope. |
1606 // Parameters must be allocated first, if any. | 1591 // Parameters must be allocated first, if any. |
1607 if (is_declaration_scope()) { | 1592 if (is_declaration_scope()) { |
1608 if (is_module_scope()) { | 1593 if (is_module_scope()) { |
1609 AsModuleScope()->AllocateModuleVariables(); | 1594 AsModuleScope()->AllocateModuleVariables(); |
1610 } else if (is_function_scope()) { | 1595 } else if (is_function_scope()) { |
1611 AsDeclarationScope()->AllocateParameterLocals(); | 1596 AsDeclarationScope()->AllocateParameterLocals(); |
(...skipping 12 matching lines...) Expand all Loading... | |
1624 (is_block_scope() && is_declaration_scope() && calls_sloppy_eval()); | 1609 (is_block_scope() && is_declaration_scope() && calls_sloppy_eval()); |
1625 | 1610 |
1626 // If we didn't allocate any locals in the local context, then we only | 1611 // If we didn't allocate any locals in the local context, then we only |
1627 // need the minimal number of slots if we must have a context. | 1612 // need the minimal number of slots if we must have a context. |
1628 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) { | 1613 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) { |
1629 num_heap_slots_ = 0; | 1614 num_heap_slots_ = 0; |
1630 } | 1615 } |
1631 | 1616 |
1632 // Allocation done. | 1617 // Allocation done. |
1633 DCHECK(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); | 1618 DCHECK(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); |
1619 | |
1620 // Create ScopeInfo. | |
1621 DCHECK(scope_info_.is_null()); | |
1622 scope_info_ = ScopeInfo::Create(isolate, zone(), this); | |
1623 | |
1624 // Allocate variables for inner scopes. | |
1625 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | |
1626 scope->AllocateVariablesRecursively(isolate); | |
adamk
2016/08/26 18:41:08
For stack-allocated block-scoped variables, this m
| |
1627 } | |
1634 } | 1628 } |
1635 | 1629 |
1636 | 1630 |
1637 int Scope::StackLocalCount() const { | 1631 int Scope::StackLocalCount() const { |
1638 Variable* function = | 1632 Variable* function = |
1639 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; | 1633 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; |
1640 return num_stack_slots() - | 1634 return num_stack_slots() - |
1641 (function != nullptr && function->IsStackLocal() ? 1 : 0); | 1635 (function != nullptr && function->IsStackLocal() ? 1 : 0); |
1642 } | 1636 } |
1643 | 1637 |
1644 | 1638 |
1645 int Scope::ContextLocalCount() const { | 1639 int Scope::ContextLocalCount() const { |
1646 if (num_heap_slots() == 0) return 0; | 1640 if (num_heap_slots() == 0) return 0; |
1647 Variable* function = | 1641 Variable* function = |
1648 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; | 1642 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; |
1649 bool is_function_var_in_context = | 1643 bool is_function_var_in_context = |
1650 function != nullptr && function->IsContextSlot(); | 1644 function != nullptr && function->IsContextSlot(); |
1651 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - | 1645 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - |
1652 (is_function_var_in_context ? 1 : 0); | 1646 (is_function_var_in_context ? 1 : 0); |
1653 } | 1647 } |
1654 | 1648 |
1655 | 1649 |
1656 int Scope::ContextGlobalCount() const { return num_global_slots(); } | 1650 int Scope::ContextGlobalCount() const { return num_global_slots(); } |
1657 | 1651 |
1658 } // namespace internal | 1652 } // namespace internal |
1659 } // namespace v8 | 1653 } // namespace v8 |
OLD | NEW |