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 831 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
842 outer_scope_calls_sloppy_eval = | 842 outer_scope_calls_sloppy_eval = |
843 outer_scope_->outer_scope_calls_sloppy_eval() | | 843 outer_scope_->outer_scope_calls_sloppy_eval() | |
844 outer_scope_->calls_sloppy_eval(); | 844 outer_scope_->calls_sloppy_eval(); |
845 } | 845 } |
846 PropagateScopeInfo(outer_scope_calls_sloppy_eval); | 846 PropagateScopeInfo(outer_scope_calls_sloppy_eval); |
847 | 847 |
848 // 2) Resolve variables. | 848 // 2) Resolve variables. |
849 ResolveVariablesRecursively(info, factory); | 849 ResolveVariablesRecursively(info, factory); |
850 | 850 |
851 // 3) Allocate variables. | 851 // 3) Allocate variables. |
852 AllocateVariablesRecursively(info->ast_value_factory()); | 852 AllocateVariablesRecursively(); |
853 } | 853 } |
854 | 854 |
855 | 855 |
856 bool Scope::HasTrivialContext() const { | 856 bool Scope::HasTrivialContext() const { |
857 // A function scope has a trivial context if it always is the global | 857 // A function scope has a trivial context if it always is the global |
858 // context. We iteratively scan out the context chain to see if | 858 // context. We iteratively scan out the context chain to see if |
859 // there is anything that makes this scope non-trivial; otherwise we | 859 // there is anything that makes this scope non-trivial; otherwise we |
860 // return true. | 860 // return true. |
861 for (const Scope* scope = this; scope != NULL; scope = scope->outer_scope_) { | 861 for (const Scope* scope = this; scope != NULL; scope = scope->outer_scope_) { |
862 if (scope->is_eval_scope()) return false; | 862 if (scope->is_eval_scope()) return false; |
(...skipping 736 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1599 } | 1599 } |
1600 } | 1600 } |
1601 | 1601 |
1602 void DeclarationScope::AllocateReceiver() { | 1602 void DeclarationScope::AllocateReceiver() { |
1603 if (!has_this_declaration()) return; | 1603 if (!has_this_declaration()) return; |
1604 DCHECK_NOT_NULL(receiver()); | 1604 DCHECK_NOT_NULL(receiver()); |
1605 DCHECK_EQ(receiver()->scope(), this); | 1605 DCHECK_EQ(receiver()->scope(), this); |
1606 AllocateParameter(receiver(), -1); | 1606 AllocateParameter(receiver(), -1); |
1607 } | 1607 } |
1608 | 1608 |
1609 void Scope::AllocateNonParameterLocal(Variable* var, | 1609 void Scope::AllocateNonParameterLocal(Variable* var) { |
1610 AstValueFactory* ast_value_factory) { | |
1611 DCHECK(var->scope() == this); | 1610 DCHECK(var->scope() == this); |
1612 DCHECK(var->raw_name() != ast_value_factory->dot_result_string() || | |
1613 !var->IsStackLocal()); | |
1614 if (var->IsUnallocated() && MustAllocate(var)) { | 1611 if (var->IsUnallocated() && MustAllocate(var)) { |
1615 if (MustAllocateInContext(var)) { | 1612 if (MustAllocateInContext(var)) { |
1616 AllocateHeapSlot(var); | 1613 AllocateHeapSlot(var); |
1617 } else { | 1614 } else { |
1618 AllocateStackSlot(var); | 1615 AllocateStackSlot(var); |
1619 } | 1616 } |
1620 } | 1617 } |
1621 } | 1618 } |
1622 | 1619 |
1623 void Scope::AllocateDeclaredGlobal(Variable* var, | 1620 void Scope::AllocateDeclaredGlobal(Variable* var) { |
1624 AstValueFactory* ast_value_factory) { | |
1625 DCHECK(var->scope() == this); | 1621 DCHECK(var->scope() == this); |
1626 DCHECK(var->raw_name() != ast_value_factory->dot_result_string() || | |
1627 !var->IsStackLocal()); | |
1628 if (var->IsUnallocated()) { | 1622 if (var->IsUnallocated()) { |
1629 if (var->IsStaticGlobalObjectProperty()) { | 1623 if (var->IsStaticGlobalObjectProperty()) { |
1630 DCHECK_EQ(-1, var->index()); | 1624 DCHECK_EQ(-1, var->index()); |
1631 DCHECK(var->name()->IsString()); | 1625 DCHECK(var->name()->IsString()); |
1632 var->AllocateTo(VariableLocation::GLOBAL, num_heap_slots_++); | 1626 var->AllocateTo(VariableLocation::GLOBAL, num_heap_slots_++); |
1633 num_global_slots_++; | 1627 num_global_slots_++; |
1634 } else { | 1628 } else { |
1635 // There must be only DYNAMIC_GLOBAL in the script scope. | 1629 // There must be only DYNAMIC_GLOBAL in the script scope. |
1636 DCHECK(!is_script_scope() || DYNAMIC_GLOBAL == var->mode()); | 1630 DCHECK(!is_script_scope() || DYNAMIC_GLOBAL == var->mode()); |
1637 } | 1631 } |
1638 } | 1632 } |
1639 } | 1633 } |
1640 | 1634 |
1641 void Scope::AllocateNonParameterLocalsAndDeclaredGlobals( | 1635 void Scope::AllocateNonParameterLocalsAndDeclaredGlobals() { |
1642 AstValueFactory* ast_value_factory) { | |
1643 // All variables that have no rewrite yet are non-parameter locals. | 1636 // All variables that have no rewrite yet are non-parameter locals. |
1644 if (is_declaration_scope()) { | 1637 if (is_declaration_scope()) { |
1645 ZoneList<Variable*>* temps = AsDeclarationScope()->temps(); | 1638 ZoneList<Variable*>* temps = AsDeclarationScope()->temps(); |
1646 for (int i = 0; i < temps->length(); i++) { | 1639 for (int i = 0; i < temps->length(); i++) { |
1647 AllocateNonParameterLocal((*temps)[i], ast_value_factory); | 1640 AllocateNonParameterLocal((*temps)[i]); |
1648 } | 1641 } |
1649 } | 1642 } |
1650 | 1643 |
1651 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); | 1644 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); |
1652 for (VariableMap::Entry* p = variables_.Start(); | 1645 for (VariableMap::Entry* p = variables_.Start(); |
1653 p != NULL; | 1646 p != NULL; |
1654 p = variables_.Next(p)) { | 1647 p = variables_.Next(p)) { |
1655 Variable* var = reinterpret_cast<Variable*>(p->value); | 1648 Variable* var = reinterpret_cast<Variable*>(p->value); |
1656 vars.Add(VarAndOrder(var, p->order), zone()); | 1649 vars.Add(VarAndOrder(var, p->order), zone()); |
1657 } | 1650 } |
1658 vars.Sort(VarAndOrder::Compare); | 1651 vars.Sort(VarAndOrder::Compare); |
1659 int var_count = vars.length(); | 1652 int var_count = vars.length(); |
1660 for (int i = 0; i < var_count; i++) { | 1653 for (int i = 0; i < var_count; i++) { |
1661 AllocateNonParameterLocal(vars[i].var(), ast_value_factory); | 1654 AllocateNonParameterLocal(vars[i].var()); |
1662 } | 1655 } |
1663 | 1656 |
1664 if (FLAG_global_var_shortcuts) { | 1657 if (FLAG_global_var_shortcuts) { |
1665 for (int i = 0; i < var_count; i++) { | 1658 for (int i = 0; i < var_count; i++) { |
1666 AllocateDeclaredGlobal(vars[i].var(), ast_value_factory); | 1659 AllocateDeclaredGlobal(vars[i].var()); |
1667 } | 1660 } |
1668 } | 1661 } |
1669 | 1662 |
1670 if (is_declaration_scope()) { | 1663 if (is_declaration_scope()) { |
1671 AsDeclarationScope()->AllocateLocals(ast_value_factory); | 1664 AsDeclarationScope()->AllocateLocals(); |
1672 } | 1665 } |
1673 } | 1666 } |
1674 | 1667 |
1675 void DeclarationScope::AllocateLocals(AstValueFactory* ast_value_factory) { | 1668 void DeclarationScope::AllocateLocals() { |
1676 // For now, function_ must be allocated at the very end. If it gets | 1669 // For now, function_ must be allocated at the very end. If it gets |
1677 // allocated in the context, it must be the last slot in the context, | 1670 // allocated in the context, it must be the last slot in the context, |
1678 // because of the current ScopeInfo implementation (see | 1671 // because of the current ScopeInfo implementation (see |
1679 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). | 1672 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). |
1680 if (function_ != nullptr) { | 1673 if (function_ != nullptr) { |
1681 AllocateNonParameterLocal(function_, ast_value_factory); | 1674 AllocateNonParameterLocal(function_); |
1682 } | 1675 } |
1683 | 1676 |
1684 if (rest_parameter_ != nullptr) { | 1677 if (rest_parameter_ != nullptr) { |
1685 AllocateNonParameterLocal(rest_parameter_, ast_value_factory); | 1678 AllocateNonParameterLocal(rest_parameter_); |
1686 } | 1679 } |
1687 | 1680 |
1688 if (new_target_ != nullptr && !MustAllocate(new_target_)) { | 1681 if (new_target_ != nullptr && !MustAllocate(new_target_)) { |
1689 new_target_ = nullptr; | 1682 new_target_ = nullptr; |
1690 } | 1683 } |
1691 | 1684 |
1692 if (this_function_ != nullptr && !MustAllocate(this_function_)) { | 1685 if (this_function_ != nullptr && !MustAllocate(this_function_)) { |
1693 this_function_ = nullptr; | 1686 this_function_ = nullptr; |
1694 } | 1687 } |
1695 } | 1688 } |
1696 | 1689 |
1697 void DeclarationScope::AllocateModuleVariables() { | 1690 void DeclarationScope::AllocateModuleVariables() { |
1698 for (auto it = module()->regular_imports().begin(); | 1691 for (auto it = module()->regular_imports().begin(); |
1699 it != module()->regular_imports().end(); ++it) { | 1692 it != module()->regular_imports().end(); ++it) { |
1700 Variable* var = LookupLocal(it->second->local_name); | 1693 Variable* var = LookupLocal(it->second->local_name); |
1701 // TODO(neis): Use a meaningful index. | 1694 // TODO(neis): Use a meaningful index. |
1702 var->AllocateTo(VariableLocation::MODULE, 42); | 1695 var->AllocateTo(VariableLocation::MODULE, 42); |
1703 } | 1696 } |
1704 | 1697 |
1705 for (auto entry : module()->exports()) { | 1698 for (auto entry : module()->exports()) { |
1706 if (entry->local_name == nullptr) continue; | 1699 if (entry->local_name == nullptr) continue; |
1707 Variable* var = LookupLocal(entry->local_name); | 1700 Variable* var = LookupLocal(entry->local_name); |
1708 var->AllocateTo(VariableLocation::MODULE, 42); | 1701 var->AllocateTo(VariableLocation::MODULE, 42); |
1709 } | 1702 } |
1710 } | 1703 } |
1711 | 1704 |
1712 void Scope::AllocateVariablesRecursively(AstValueFactory* ast_value_factory) { | 1705 void Scope::AllocateVariablesRecursively() { |
1713 if (!already_resolved()) { | 1706 if (!already_resolved()) { |
1714 num_stack_slots_ = 0; | 1707 num_stack_slots_ = 0; |
1715 } | 1708 } |
1716 // Allocate variables for inner scopes. | 1709 // Allocate variables for inner scopes. |
1717 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 1710 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
1718 scope->AllocateVariablesRecursively(ast_value_factory); | 1711 scope->AllocateVariablesRecursively(); |
1719 } | 1712 } |
1720 | 1713 |
1721 // If scope is already resolved, we still need to allocate | 1714 // If scope is already resolved, we still need to allocate |
1722 // variables in inner scopes which might not have been resolved yet. | 1715 // variables in inner scopes which might not have been resolved yet. |
1723 if (already_resolved()) return; | 1716 if (already_resolved()) return; |
1724 // The number of slots required for variables. | 1717 // The number of slots required for variables. |
1725 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; | 1718 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; |
1726 | 1719 |
1727 // Allocate variables for this scope. | 1720 // Allocate variables for this scope. |
1728 // Parameters must be allocated first, if any. | 1721 // Parameters must be allocated first, if any. |
1729 if (is_declaration_scope()) { | 1722 if (is_declaration_scope()) { |
1730 if (is_module_scope()) { | 1723 if (is_module_scope()) { |
1731 AsDeclarationScope()->AllocateModuleVariables(); | 1724 AsDeclarationScope()->AllocateModuleVariables(); |
1732 } else if (is_function_scope()) { | 1725 } else if (is_function_scope()) { |
1733 AsDeclarationScope()->AllocateParameterLocals(); | 1726 AsDeclarationScope()->AllocateParameterLocals(); |
1734 } | 1727 } |
1735 AsDeclarationScope()->AllocateReceiver(); | 1728 AsDeclarationScope()->AllocateReceiver(); |
1736 } | 1729 } |
1737 AllocateNonParameterLocalsAndDeclaredGlobals(ast_value_factory); | 1730 AllocateNonParameterLocalsAndDeclaredGlobals(); |
1738 | 1731 |
1739 // Force allocation of a context for this scope if necessary. For a 'with' | 1732 // Force allocation of a context for this scope if necessary. For a 'with' |
1740 // scope and for a function scope that makes an 'eval' call we need a context, | 1733 // scope and for a function scope that makes an 'eval' call we need a context, |
1741 // even if no local variables were statically allocated in the scope. | 1734 // even if no local variables were statically allocated in the scope. |
1742 // Likewise for modules. | 1735 // Likewise for modules. |
1743 bool must_have_context = | 1736 bool must_have_context = |
1744 is_with_scope() || is_module_scope() || | 1737 is_with_scope() || is_module_scope() || |
1745 (is_function_scope() && calls_sloppy_eval()) || | 1738 (is_function_scope() && calls_sloppy_eval()) || |
1746 (is_block_scope() && is_declaration_scope() && calls_sloppy_eval()); | 1739 (is_block_scope() && is_declaration_scope() && calls_sloppy_eval()); |
1747 | 1740 |
(...skipping 24 matching lines...) Expand all Loading... |
1772 function != nullptr && function->IsContextSlot(); | 1765 function != nullptr && function->IsContextSlot(); |
1773 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - | 1766 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - |
1774 (is_function_var_in_context ? 1 : 0); | 1767 (is_function_var_in_context ? 1 : 0); |
1775 } | 1768 } |
1776 | 1769 |
1777 | 1770 |
1778 int Scope::ContextGlobalCount() const { return num_global_slots(); } | 1771 int Scope::ContextGlobalCount() const { return num_global_slots(); } |
1779 | 1772 |
1780 } // namespace internal | 1773 } // namespace internal |
1781 } // namespace v8 | 1774 } // namespace v8 |
OLD | NEW |