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 #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 |