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 "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
9 #include "src/messages.h" | 9 #include "src/messages.h" |
10 #include "src/parsing/parser.h" // for ParseInfo | 10 #include "src/parsing/parser.h" // for ParseInfo |
(...skipping 749 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
760 outer_scope_calls_sloppy_eval = | 760 outer_scope_calls_sloppy_eval = |
761 outer_scope_->outer_scope_calls_sloppy_eval() | | 761 outer_scope_->outer_scope_calls_sloppy_eval() | |
762 outer_scope_->calls_sloppy_eval(); | 762 outer_scope_->calls_sloppy_eval(); |
763 } | 763 } |
764 PropagateScopeInfo(outer_scope_calls_sloppy_eval); | 764 PropagateScopeInfo(outer_scope_calls_sloppy_eval); |
765 | 765 |
766 // 2) Resolve variables. | 766 // 2) Resolve variables. |
767 if (!ResolveVariablesRecursively(info, factory)) return false; | 767 if (!ResolveVariablesRecursively(info, factory)) return false; |
768 | 768 |
769 // 3) Allocate variables. | 769 // 3) Allocate variables. |
770 if (info->is_module()) AllocateModuleVariables(); | |
770 AllocateVariablesRecursively(info->ast_value_factory()); | 771 AllocateVariablesRecursively(info->ast_value_factory()); |
771 | 772 |
772 return true; | 773 return true; |
773 } | 774 } |
774 | 775 |
775 | 776 |
776 bool Scope::HasTrivialContext() const { | 777 bool Scope::HasTrivialContext() const { |
777 // A function scope has a trivial context if it always is the global | 778 // A function scope has a trivial context if it always is the global |
778 // context. We iteratively scan out the context chain to see if | 779 // context. We iteratively scan out the context chain to see if |
779 // there is anything that makes this scope non-trivial; otherwise we | 780 // there is anything that makes this scope non-trivial; otherwise we |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
850 | 851 |
851 | 852 |
852 Scope* Scope::ClosureScope() { | 853 Scope* Scope::ClosureScope() { |
853 Scope* scope = this; | 854 Scope* scope = this; |
854 while (!scope->is_declaration_scope() || scope->is_block_scope()) { | 855 while (!scope->is_declaration_scope() || scope->is_block_scope()) { |
855 scope = scope->outer_scope(); | 856 scope = scope->outer_scope(); |
856 } | 857 } |
857 return scope; | 858 return scope; |
858 } | 859 } |
859 | 860 |
861 Scope* Scope::ModuleScope() { | |
862 Scope* scope = this; | |
863 while (!scope->is_script_scope()) scope = scope->outer_scope(); | |
864 scope = scope->inner_scope(); | |
adamk
2016/08/02 16:34:31
Why not just walk up till you hit the module scope
neis
2016/08/03 09:16:30
Because "this" may already be the script scope. Se
adamk
2016/08/03 17:51:26
But we'll walk _down_ the scope tree as part of an
| |
865 return (scope == nullptr || !scope->is_module_scope()) ? nullptr : scope; | |
866 } | |
860 | 867 |
861 Scope* Scope::ReceiverScope() { | 868 Scope* Scope::ReceiverScope() { |
862 Scope* scope = this; | 869 Scope* scope = this; |
863 while (!scope->is_script_scope() && | 870 while (!scope->is_script_scope() && |
864 (!scope->is_function_scope() || scope->is_arrow_scope())) { | 871 (!scope->is_function_scope() || scope->is_arrow_scope())) { |
865 scope = scope->outer_scope(); | 872 scope = scope->outer_scope(); |
866 } | 873 } |
867 return scope; | 874 return scope; |
868 } | 875 } |
869 | 876 |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
972 break; | 979 break; |
973 case VariableLocation::CONTEXT: | 980 case VariableLocation::CONTEXT: |
974 PrintF("context[%d]", var->index()); | 981 PrintF("context[%d]", var->index()); |
975 break; | 982 break; |
976 case VariableLocation::GLOBAL: | 983 case VariableLocation::GLOBAL: |
977 PrintF("global[%d]", var->index()); | 984 PrintF("global[%d]", var->index()); |
978 break; | 985 break; |
979 case VariableLocation::LOOKUP: | 986 case VariableLocation::LOOKUP: |
980 PrintF("lookup"); | 987 PrintF("lookup"); |
981 break; | 988 break; |
989 case VariableLocation::MODULE: | |
990 PrintF("module"); | |
991 break; | |
982 } | 992 } |
983 } | 993 } |
984 | 994 |
985 | 995 |
986 static void PrintVar(int indent, Variable* var) { | 996 static void PrintVar(int indent, Variable* var) { |
987 if (var->is_used() || !var->IsUnallocated()) { | 997 if (var->is_used() || !var->IsUnallocated()) { |
988 Indent(indent, Variable::Mode2String(var->mode())); | 998 Indent(indent, Variable::Mode2String(var->mode())); |
989 PrintF(" "); | 999 PrintF(" "); |
990 if (var->raw_name()->IsEmpty()) | 1000 if (var->raw_name()->IsEmpty()) |
991 PrintF(".%p", reinterpret_cast<void*>(var)); | 1001 PrintF(".%p", reinterpret_cast<void*>(var)); |
(...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1581 | 1591 |
1582 if (new_target_ != nullptr && !MustAllocate(new_target_)) { | 1592 if (new_target_ != nullptr && !MustAllocate(new_target_)) { |
1583 new_target_ = nullptr; | 1593 new_target_ = nullptr; |
1584 } | 1594 } |
1585 | 1595 |
1586 if (this_function_ != nullptr && !MustAllocate(this_function_)) { | 1596 if (this_function_ != nullptr && !MustAllocate(this_function_)) { |
1587 this_function_ = nullptr; | 1597 this_function_ = nullptr; |
1588 } | 1598 } |
1589 } | 1599 } |
1590 | 1600 |
1601 void Scope::AllocateModuleVariables() { | |
1602 Scope* module_scope = ModuleScope(); | |
adamk
2016/08/02 16:34:31
Does this need to walk up to the ModuleScope? I wo
neis
2016/08/03 09:16:30
I'm calling AllocateModuleVariables inside Allocat
adamk
2016/08/03 17:51:26
See above, I was imagining that we'd check is_modu
| |
1603 ModuleDescriptor* mod = module_scope->module(); | |
1604 for (auto entry : mod->imports()) { | |
1605 if (entry->local_name == nullptr) continue; | |
1606 if (entry->import_name == nullptr) continue; // Namespace import. | |
1607 Variable* var = module_scope->LookupLocal(entry->local_name); | |
1608 // TODO(neis): Use a meaningful index. | |
1609 var->AllocateTo(VariableLocation::MODULE, 42); | |
adamk
2016/08/02 16:34:31
For imports, I think we want to check Scope::MustA
neis
2016/08/03 09:16:30
Not sure I understand. Setting the VariableLocatio
adamk
2016/08/03 17:51:26
My understanding may be wrong, but I thought that
| |
1610 } | |
1611 for (auto entry : mod->exports()) { | |
1612 if (entry->local_name == nullptr) continue; | |
1613 Variable* var = module_scope->LookupLocal(entry->local_name); | |
1614 var->AllocateTo(VariableLocation::MODULE, 42); | |
1615 } | |
1616 } | |
1617 | |
1591 void Scope::AllocateVariablesRecursively(AstValueFactory* ast_value_factory) { | 1618 void Scope::AllocateVariablesRecursively(AstValueFactory* ast_value_factory) { |
1592 if (!already_resolved()) { | 1619 if (!already_resolved()) { |
1593 num_stack_slots_ = 0; | 1620 num_stack_slots_ = 0; |
1594 } | 1621 } |
1595 // Allocate variables for inner scopes. | 1622 // Allocate variables for inner scopes. |
1596 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 1623 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
1597 scope->AllocateVariablesRecursively(ast_value_factory); | 1624 scope->AllocateVariablesRecursively(ast_value_factory); |
1598 } | 1625 } |
1599 | 1626 |
1600 // If scope is already resolved, we still need to allocate | 1627 // If scope is already resolved, we still need to allocate |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1641 function_ != NULL && function_->proxy()->var()->IsContextSlot(); | 1668 function_ != NULL && function_->proxy()->var()->IsContextSlot(); |
1642 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - | 1669 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - |
1643 (is_function_var_in_context ? 1 : 0); | 1670 (is_function_var_in_context ? 1 : 0); |
1644 } | 1671 } |
1645 | 1672 |
1646 | 1673 |
1647 int Scope::ContextGlobalCount() const { return num_global_slots(); } | 1674 int Scope::ContextGlobalCount() const { return num_global_slots(); } |
1648 | 1675 |
1649 } // namespace internal | 1676 } // namespace internal |
1650 } // namespace v8 | 1677 } // namespace v8 |
OLD | NEW |