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