| 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/ast/ast.h" | 10 #include "src/ast/ast.h" |
| (...skipping 988 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 999 return var; | 999 return var; |
| 1000 } | 1000 } |
| 1001 | 1001 |
| 1002 VariableProxy* Scope::NewUnresolved(AstNodeFactory* factory, | 1002 VariableProxy* Scope::NewUnresolved(AstNodeFactory* factory, |
| 1003 const AstRawString* name, | 1003 const AstRawString* name, |
| 1004 int start_position, VariableKind kind) { | 1004 int start_position, VariableKind kind) { |
| 1005 // Note that we must not share the unresolved variables with | 1005 // Note that we must not share the unresolved variables with |
| 1006 // the same name because they may be removed selectively via | 1006 // the same name because they may be removed selectively via |
| 1007 // RemoveUnresolved(). | 1007 // RemoveUnresolved(). |
| 1008 DCHECK(!already_resolved_); | 1008 DCHECK(!already_resolved_); |
| 1009 DCHECK_EQ(!needs_migration_, factory->zone() == zone()); | 1009 DCHECK_EQ(factory->zone(), zone()); |
| 1010 VariableProxy* proxy = factory->NewVariableProxy(name, kind, start_position); | 1010 VariableProxy* proxy = factory->NewVariableProxy(name, kind, start_position); |
| 1011 proxy->set_next_unresolved(unresolved_); | 1011 proxy->set_next_unresolved(unresolved_); |
| 1012 unresolved_ = proxy; | 1012 unresolved_ = proxy; |
| 1013 return proxy; | 1013 return proxy; |
| 1014 } | 1014 } |
| 1015 | 1015 |
| 1016 void Scope::AddUnresolved(VariableProxy* proxy) { | 1016 void Scope::AddUnresolved(VariableProxy* proxy) { |
| 1017 DCHECK(!already_resolved_); | 1017 DCHECK(!already_resolved_); |
| 1018 DCHECK(!proxy->is_resolved()); | 1018 DCHECK(!proxy->is_resolved()); |
| 1019 proxy->set_next_unresolved(unresolved_); | 1019 proxy->set_next_unresolved(unresolved_); |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1282 } | 1282 } |
| 1283 | 1283 |
| 1284 void DeclarationScope::ResetAfterPreparsing(AstValueFactory* ast_value_factory, | 1284 void DeclarationScope::ResetAfterPreparsing(AstValueFactory* ast_value_factory, |
| 1285 bool aborted) { | 1285 bool aborted) { |
| 1286 DCHECK(is_function_scope()); | 1286 DCHECK(is_function_scope()); |
| 1287 | 1287 |
| 1288 // Reset all non-trivial members. | 1288 // Reset all non-trivial members. |
| 1289 params_.Clear(); | 1289 params_.Clear(); |
| 1290 decls_.Clear(); | 1290 decls_.Clear(); |
| 1291 locals_.Clear(); | 1291 locals_.Clear(); |
| 1292 sloppy_block_function_map_.Clear(); | |
| 1293 variables_.Clear(); | |
| 1294 // Make sure we won't walk the scope tree from here on. | |
| 1295 inner_scope_ = nullptr; | 1292 inner_scope_ = nullptr; |
| 1296 unresolved_ = nullptr; | 1293 unresolved_ = nullptr; |
| 1297 | 1294 |
| 1298 if (aborted && !IsArrowFunction(function_kind_)) { | 1295 if (aborted) { |
| 1299 DeclareDefaultFunctionVariables(ast_value_factory); | 1296 // Prepare scope for use in the outer zone. |
| 1297 zone_ = ast_value_factory->zone(); |
| 1298 variables_.Reset(ZoneAllocationPolicy(zone_)); |
| 1299 sloppy_block_function_map_.Reset(ZoneAllocationPolicy(zone_)); |
| 1300 if (!IsArrowFunction(function_kind_)) { |
| 1301 DeclareDefaultFunctionVariables(ast_value_factory); |
| 1302 } |
| 1303 } else { |
| 1304 // Make sure this scope isn't used for allocation anymore. |
| 1305 zone_ = nullptr; |
| 1306 variables_.Invalidate(); |
| 1307 sloppy_block_function_map_.Invalidate(); |
| 1300 } | 1308 } |
| 1301 | 1309 |
| 1302 #ifdef DEBUG | 1310 #ifdef DEBUG |
| 1303 needs_migration_ = false; | 1311 needs_migration_ = false; |
| 1304 #endif | 1312 #endif |
| 1305 | 1313 |
| 1306 is_lazily_parsed_ = !aborted; | 1314 is_lazily_parsed_ = !aborted; |
| 1307 } | 1315 } |
| 1308 | 1316 |
| 1309 void DeclarationScope::AnalyzePartially(AstNodeFactory* ast_node_factory) { | 1317 void DeclarationScope::AnalyzePartially(AstNodeFactory* ast_node_factory) { |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1495 Indent(n1, "// "); | 1503 Indent(n1, "// "); |
| 1496 PrintF("%d heap slots\n", num_heap_slots_); | 1504 PrintF("%d heap slots\n", num_heap_slots_); |
| 1497 } | 1505 } |
| 1498 | 1506 |
| 1499 // Print locals. | 1507 // Print locals. |
| 1500 if (function != nullptr) { | 1508 if (function != nullptr) { |
| 1501 Indent(n1, "// function var:\n"); | 1509 Indent(n1, "// function var:\n"); |
| 1502 PrintVar(n1, function); | 1510 PrintVar(n1, function); |
| 1503 } | 1511 } |
| 1504 | 1512 |
| 1505 if (variables_.Start() != NULL) { | 1513 if (variables_.occupancy() != 0) { |
| 1506 Indent(n1, "// local vars:\n"); | 1514 Indent(n1, "// local vars:\n"); |
| 1507 PrintMap(n1, &variables_, true); | 1515 PrintMap(n1, &variables_, true); |
| 1508 | 1516 |
| 1509 Indent(n1, "// dynamic vars:\n"); | 1517 Indent(n1, "// dynamic vars:\n"); |
| 1510 PrintMap(n1, &variables_, false); | 1518 PrintMap(n1, &variables_, false); |
| 1511 } | 1519 } |
| 1512 | 1520 |
| 1513 // Print inner scopes (disable by providing negative n). | 1521 // Print inner scopes (disable by providing negative n). |
| 1514 if (n >= 0) { | 1522 if (n >= 0) { |
| 1515 for (Scope* scope = inner_scope_; scope != nullptr; | 1523 for (Scope* scope = inner_scope_; scope != nullptr; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1529 CHECK_NE(kNoSourcePosition, end_position()); | 1537 CHECK_NE(kNoSourcePosition, end_position()); |
| 1530 } | 1538 } |
| 1531 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 1539 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
| 1532 scope->CheckScopePositions(); | 1540 scope->CheckScopePositions(); |
| 1533 } | 1541 } |
| 1534 } | 1542 } |
| 1535 | 1543 |
| 1536 void Scope::CheckZones() { | 1544 void Scope::CheckZones() { |
| 1537 DCHECK(!needs_migration_); | 1545 DCHECK(!needs_migration_); |
| 1538 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 1546 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
| 1547 if (scope->is_declaration_scope() && |
| 1548 scope->AsDeclarationScope()->is_lazily_parsed()) { |
| 1549 DCHECK_NULL(scope->zone()); |
| 1550 DCHECK_NULL(scope->inner_scope_); |
| 1551 continue; |
| 1552 } |
| 1539 CHECK_EQ(scope->zone(), zone()); | 1553 CHECK_EQ(scope->zone(), zone()); |
| 1540 scope->CheckZones(); | 1554 scope->CheckZones(); |
| 1541 } | 1555 } |
| 1542 } | 1556 } |
| 1543 #endif // DEBUG | 1557 #endif // DEBUG |
| 1544 | 1558 |
| 1545 Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) { | 1559 Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) { |
| 1546 // Declare a new non-local. | 1560 // Declare a new non-local. |
| 1547 DCHECK(IsDynamicVariableMode(mode)); | 1561 DCHECK(IsDynamicVariableMode(mode)); |
| 1548 Variable* var = variables_.Declare(zone(), NULL, name, mode, NORMAL_VARIABLE, | 1562 Variable* var = variables_.Declare(zone(), NULL, name, mode, NORMAL_VARIABLE, |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1716 #endif | 1730 #endif |
| 1717 | 1731 |
| 1718 DCHECK_NOT_NULL(var); | 1732 DCHECK_NOT_NULL(var); |
| 1719 if (proxy->is_assigned()) var->set_maybe_assigned(); | 1733 if (proxy->is_assigned()) var->set_maybe_assigned(); |
| 1720 if (AccessNeedsHoleCheck(var, proxy, this)) proxy->set_needs_hole_check(); | 1734 if (AccessNeedsHoleCheck(var, proxy, this)) proxy->set_needs_hole_check(); |
| 1721 proxy->BindTo(var); | 1735 proxy->BindTo(var); |
| 1722 } | 1736 } |
| 1723 | 1737 |
| 1724 void Scope::ResolveVariablesRecursively(ParseInfo* info) { | 1738 void Scope::ResolveVariablesRecursively(ParseInfo* info) { |
| 1725 DCHECK(info->script_scope()->is_script_scope()); | 1739 DCHECK(info->script_scope()->is_script_scope()); |
| 1740 // Lazy parsed declaration scopes are already partially analyzed. If there are |
| 1741 // unresolved references remaining, they just need to be resolved in outer |
| 1742 // scopes. |
| 1743 if (is_declaration_scope() && AsDeclarationScope()->is_lazily_parsed()) { |
| 1744 DCHECK(variables_.occupancy() == 0); |
| 1745 for (VariableProxy* proxy = unresolved_; proxy != nullptr; |
| 1746 proxy = proxy->next_unresolved()) { |
| 1747 Variable* var = outer_scope()->LookupRecursive(proxy, nullptr); |
| 1748 if (!var->is_dynamic()) { |
| 1749 var->set_is_used(); |
| 1750 var->ForceContextAllocation(); |
| 1751 if (proxy->is_assigned()) var->set_maybe_assigned(); |
| 1752 } |
| 1753 } |
| 1754 } else { |
| 1755 // Resolve unresolved variables for this scope. |
| 1756 for (VariableProxy* proxy = unresolved_; proxy != nullptr; |
| 1757 proxy = proxy->next_unresolved()) { |
| 1758 ResolveVariable(info, proxy); |
| 1759 } |
| 1726 | 1760 |
| 1727 // Resolve unresolved variables for this scope. | 1761 // Resolve unresolved variables for inner scopes. |
| 1728 for (VariableProxy* proxy = unresolved_; proxy != nullptr; | 1762 for (Scope* scope = inner_scope_; scope != nullptr; |
| 1729 proxy = proxy->next_unresolved()) { | 1763 scope = scope->sibling_) { |
| 1730 ResolveVariable(info, proxy); | 1764 scope->ResolveVariablesRecursively(info); |
| 1731 } | 1765 } |
| 1732 | |
| 1733 // Resolve unresolved variables for inner scopes. | |
| 1734 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | |
| 1735 scope->ResolveVariablesRecursively(info); | |
| 1736 } | 1766 } |
| 1737 } | 1767 } |
| 1738 | 1768 |
| 1739 VariableProxy* Scope::FetchFreeVariables(DeclarationScope* max_outer_scope, | 1769 VariableProxy* Scope::FetchFreeVariables(DeclarationScope* max_outer_scope, |
| 1740 bool try_to_resolve, ParseInfo* info, | 1770 bool try_to_resolve, ParseInfo* info, |
| 1741 VariableProxy* stack) { | 1771 VariableProxy* stack) { |
| 1772 // Lazy parsed declaration scopes are already partially analyzed. If there are |
| 1773 // unresolved references remaining, they just need to be resolved in outer |
| 1774 // scopes. |
| 1775 Scope* lookup = |
| 1776 is_declaration_scope() && AsDeclarationScope()->is_lazily_parsed() |
| 1777 ? outer_scope() |
| 1778 : this; |
| 1742 for (VariableProxy *proxy = unresolved_, *next = nullptr; proxy != nullptr; | 1779 for (VariableProxy *proxy = unresolved_, *next = nullptr; proxy != nullptr; |
| 1743 proxy = next) { | 1780 proxy = next) { |
| 1744 next = proxy->next_unresolved(); | 1781 next = proxy->next_unresolved(); |
| 1745 DCHECK(!proxy->is_resolved()); | 1782 DCHECK(!proxy->is_resolved()); |
| 1746 Variable* var = nullptr; | 1783 Variable* var = nullptr; |
| 1747 if (try_to_resolve) { | 1784 if (try_to_resolve) { |
| 1748 var = LookupRecursive(proxy, max_outer_scope->outer_scope()); | 1785 var = lookup->LookupRecursive(proxy, max_outer_scope->outer_scope()); |
| 1749 } | 1786 } |
| 1750 if (var == nullptr) { | 1787 if (var == nullptr) { |
| 1751 proxy->set_next_unresolved(stack); | 1788 proxy->set_next_unresolved(stack); |
| 1752 stack = proxy; | 1789 stack = proxy; |
| 1753 } else if (info != nullptr) { | 1790 } else if (info != nullptr) { |
| 1791 // In this case we need to leave scopes in a way that they can be |
| 1792 // allocated. If we resolved variables from lazy parsed scopes, we need to |
| 1793 // context allocate the var. |
| 1754 ResolveTo(info, proxy, var); | 1794 ResolveTo(info, proxy, var); |
| 1795 if (!var->is_dynamic() && lookup != this) var->ForceContextAllocation(); |
| 1755 } else { | 1796 } else { |
| 1756 var->set_is_used(); | 1797 var->set_is_used(); |
| 1757 } | 1798 } |
| 1758 } | 1799 } |
| 1759 | 1800 |
| 1760 // Clear unresolved_ as it's in an inconsistent state. | 1801 // Clear unresolved_ as it's in an inconsistent state. |
| 1761 unresolved_ = nullptr; | 1802 unresolved_ = nullptr; |
| 1762 | 1803 |
| 1763 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 1804 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
| 1764 stack = | 1805 stack = |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2030 Variable* function = | 2071 Variable* function = |
| 2031 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; | 2072 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; |
| 2032 bool is_function_var_in_context = | 2073 bool is_function_var_in_context = |
| 2033 function != nullptr && function->IsContextSlot(); | 2074 function != nullptr && function->IsContextSlot(); |
| 2034 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 2075 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
| 2035 (is_function_var_in_context ? 1 : 0); | 2076 (is_function_var_in_context ? 1 : 0); |
| 2036 } | 2077 } |
| 2037 | 2078 |
| 2038 } // namespace internal | 2079 } // namespace internal |
| 2039 } // namespace v8 | 2080 } // namespace v8 |
| OLD | NEW |