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 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 } | 89 } |
90 | 90 |
91 | 91 |
92 // ---------------------------------------------------------------------------- | 92 // ---------------------------------------------------------------------------- |
93 // Implementation of Scope | 93 // Implementation of Scope |
94 | 94 |
95 Scope::Scope(Zone* zone) | 95 Scope::Scope(Zone* zone) |
96 : zone_(zone), | 96 : zone_(zone), |
97 outer_scope_(nullptr), | 97 outer_scope_(nullptr), |
98 variables_(zone), | 98 variables_(zone), |
99 locals_(4, zone), | |
100 scope_type_(SCRIPT_SCOPE) { | 99 scope_type_(SCRIPT_SCOPE) { |
101 SetDefaults(); | 100 SetDefaults(); |
102 } | 101 } |
103 | 102 |
104 Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type) | 103 Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type) |
105 : zone_(zone), | 104 : zone_(zone), |
106 outer_scope_(outer_scope), | 105 outer_scope_(outer_scope), |
107 variables_(zone), | 106 variables_(zone), |
108 locals_(4, zone), | |
109 scope_type_(scope_type) { | 107 scope_type_(scope_type) { |
110 DCHECK_NE(SCRIPT_SCOPE, scope_type); | 108 DCHECK_NE(SCRIPT_SCOPE, scope_type); |
111 SetDefaults(); | 109 SetDefaults(); |
112 set_language_mode(outer_scope->language_mode()); | 110 set_language_mode(outer_scope->language_mode()); |
113 force_context_allocation_ = | 111 force_context_allocation_ = |
114 !is_function_scope() && outer_scope->has_forced_context_allocation(); | 112 !is_function_scope() && outer_scope->has_forced_context_allocation(); |
115 outer_scope_->AddInnerScope(this); | 113 outer_scope_->AddInnerScope(this); |
116 } | 114 } |
117 | 115 |
118 Scope::Snapshot::Snapshot(Scope* scope) | 116 Scope::Snapshot::Snapshot(Scope* scope) |
119 : outer_scope_(scope), | 117 : outer_scope_(scope), |
120 top_inner_scope_(scope->inner_scope_), | 118 top_inner_scope_(scope->inner_scope_), |
121 top_unresolved_(scope->unresolved_), | 119 top_unresolved_(scope->unresolved_), |
122 top_local_(scope->GetClosureScope()->locals_.length()), | 120 top_local_(scope->GetClosureScope()->locals_.end()), |
123 top_decl_(scope->GetClosureScope()->decls_.end()) {} | 121 top_decl_(scope->GetClosureScope()->decls_.end()) {} |
124 | 122 |
125 DeclarationScope::DeclarationScope(Zone* zone, | 123 DeclarationScope::DeclarationScope(Zone* zone, |
126 AstValueFactory* ast_value_factory) | 124 AstValueFactory* ast_value_factory) |
127 : Scope(zone), | 125 : Scope(zone), |
128 function_kind_(kNormalFunction), | 126 function_kind_(kNormalFunction), |
129 params_(4, zone), | 127 params_(4, zone), |
130 sloppy_block_function_map_(zone) { | 128 sloppy_block_function_map_(zone) { |
131 DCHECK_EQ(scope_type_, SCRIPT_SCOPE); | 129 DCHECK_EQ(scope_type_, SCRIPT_SCOPE); |
132 SetDefaults(); | 130 SetDefaults(); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 ModuleInfoEntry::cast(regular_imports->get(i)), isolate); | 200 ModuleInfoEntry::cast(regular_imports->get(i)), isolate); |
203 module_descriptor_->AddRegularImport(ModuleDescriptor::Entry::Deserialize( | 201 module_descriptor_->AddRegularImport(ModuleDescriptor::Entry::Deserialize( |
204 isolate, avfactory, serialized_entry)); | 202 isolate, avfactory, serialized_entry)); |
205 } | 203 } |
206 } | 204 } |
207 | 205 |
208 Scope::Scope(Zone* zone, ScopeType scope_type, Handle<ScopeInfo> scope_info) | 206 Scope::Scope(Zone* zone, ScopeType scope_type, Handle<ScopeInfo> scope_info) |
209 : zone_(zone), | 207 : zone_(zone), |
210 outer_scope_(nullptr), | 208 outer_scope_(nullptr), |
211 variables_(zone), | 209 variables_(zone), |
212 locals_(0, zone), | |
213 scope_info_(scope_info), | 210 scope_info_(scope_info), |
214 scope_type_(scope_type) { | 211 scope_type_(scope_type) { |
215 DCHECK(!scope_info.is_null()); | 212 DCHECK(!scope_info.is_null()); |
216 SetDefaults(); | 213 SetDefaults(); |
217 #ifdef DEBUG | 214 #ifdef DEBUG |
218 already_resolved_ = true; | 215 already_resolved_ = true; |
219 #endif | 216 #endif |
220 if (scope_info->CallsEval()) RecordEvalCall(); | 217 if (scope_info->CallsEval()) RecordEvalCall(); |
221 set_language_mode(scope_info->language_mode()); | 218 set_language_mode(scope_info->language_mode()); |
222 num_heap_slots_ = scope_info->ContextLength(); | 219 num_heap_slots_ = scope_info->ContextLength(); |
223 DCHECK_LE(Context::MIN_CONTEXT_SLOTS, num_heap_slots_); | 220 DCHECK_LE(Context::MIN_CONTEXT_SLOTS, num_heap_slots_); |
224 } | 221 } |
225 | 222 |
226 DeclarationScope::DeclarationScope(Zone* zone, ScopeType scope_type, | 223 DeclarationScope::DeclarationScope(Zone* zone, ScopeType scope_type, |
227 Handle<ScopeInfo> scope_info) | 224 Handle<ScopeInfo> scope_info) |
228 : Scope(zone, scope_type, scope_info), | 225 : Scope(zone, scope_type, scope_info), |
229 function_kind_(scope_info->function_kind()), | 226 function_kind_(scope_info->function_kind()), |
230 params_(0, zone), | 227 params_(0, zone), |
231 sloppy_block_function_map_(zone) { | 228 sloppy_block_function_map_(zone) { |
232 DCHECK_NE(scope_type, SCRIPT_SCOPE); | 229 DCHECK_NE(scope_type, SCRIPT_SCOPE); |
233 SetDefaults(); | 230 SetDefaults(); |
234 } | 231 } |
235 | 232 |
236 Scope::Scope(Zone* zone, const AstRawString* catch_variable_name, | 233 Scope::Scope(Zone* zone, const AstRawString* catch_variable_name, |
237 Handle<ScopeInfo> scope_info) | 234 Handle<ScopeInfo> scope_info) |
238 : zone_(zone), | 235 : zone_(zone), |
239 outer_scope_(nullptr), | 236 outer_scope_(nullptr), |
240 variables_(zone), | 237 variables_(zone), |
241 locals_(0, zone), | |
242 scope_info_(scope_info), | 238 scope_info_(scope_info), |
243 scope_type_(CATCH_SCOPE) { | 239 scope_type_(CATCH_SCOPE) { |
244 SetDefaults(); | 240 SetDefaults(); |
245 #ifdef DEBUG | 241 #ifdef DEBUG |
246 already_resolved_ = true; | 242 already_resolved_ = true; |
247 #endif | 243 #endif |
248 // Cache the catch variable, even though it's also available via the | 244 // Cache the catch variable, even though it's also available via the |
249 // scope_info, as the parser expects that a catch scope always has the catch | 245 // scope_info, as the parser expects that a catch scope always has the catch |
250 // variable as first and only variable. | 246 // variable as first and only variable. |
251 Variable* variable = Declare(zone, this, catch_variable_name, VAR, | 247 Variable* variable = Declare(zone, this, catch_variable_name, VAR, |
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
677 outer_scope()->unresolved_ = unresolved_; | 673 outer_scope()->unresolved_ = unresolved_; |
678 unresolved_ = nullptr; | 674 unresolved_ = nullptr; |
679 } | 675 } |
680 | 676 |
681 PropagateUsageFlagsToScope(outer_scope_); | 677 PropagateUsageFlagsToScope(outer_scope_); |
682 // This block does not need a context. | 678 // This block does not need a context. |
683 num_heap_slots_ = 0; | 679 num_heap_slots_ = 0; |
684 return NULL; | 680 return NULL; |
685 } | 681 } |
686 | 682 |
| 683 void DeclarationScope::AddLocal(Variable* var) { |
| 684 DCHECK(!already_resolved_); |
| 685 // Temporaries are only placed in ClosureScopes. |
| 686 DCHECK_EQ(GetClosureScope(), this); |
| 687 locals_.Add(var); |
| 688 } |
| 689 |
| 690 Variable* Scope::Declare(Zone* zone, Scope* scope, const AstRawString* name, |
| 691 VariableMode mode, VariableKind kind, |
| 692 InitializationFlag initialization_flag, |
| 693 MaybeAssignedFlag maybe_assigned_flag) { |
| 694 bool added; |
| 695 Variable* var = |
| 696 variables_.Declare(zone, scope, name, mode, kind, initialization_flag, |
| 697 maybe_assigned_flag, &added); |
| 698 if (added) locals_.Add(var); |
| 699 return var; |
| 700 } |
| 701 |
687 void Scope::Snapshot::Reparent(DeclarationScope* new_parent) const { | 702 void Scope::Snapshot::Reparent(DeclarationScope* new_parent) const { |
688 DCHECK_EQ(new_parent, outer_scope_->inner_scope_); | 703 DCHECK_EQ(new_parent, outer_scope_->inner_scope_); |
689 DCHECK_EQ(new_parent->outer_scope_, outer_scope_); | 704 DCHECK_EQ(new_parent->outer_scope_, outer_scope_); |
690 DCHECK_EQ(new_parent, new_parent->GetClosureScope()); | 705 DCHECK_EQ(new_parent, new_parent->GetClosureScope()); |
691 DCHECK_NULL(new_parent->inner_scope_); | 706 DCHECK_NULL(new_parent->inner_scope_); |
692 DCHECK_NULL(new_parent->unresolved_); | 707 DCHECK_NULL(new_parent->unresolved_); |
693 DCHECK_EQ(0, new_parent->locals_.length()); | 708 DCHECK(new_parent->locals_.is_empty()); |
694 Scope* inner_scope = new_parent->sibling_; | 709 Scope* inner_scope = new_parent->sibling_; |
695 if (inner_scope != top_inner_scope_) { | 710 if (inner_scope != top_inner_scope_) { |
696 for (; inner_scope->sibling() != top_inner_scope_; | 711 for (; inner_scope->sibling() != top_inner_scope_; |
697 inner_scope = inner_scope->sibling()) { | 712 inner_scope = inner_scope->sibling()) { |
698 inner_scope->outer_scope_ = new_parent; | 713 inner_scope->outer_scope_ = new_parent; |
699 DCHECK_NE(inner_scope, new_parent); | 714 DCHECK_NE(inner_scope, new_parent); |
700 } | 715 } |
701 inner_scope->outer_scope_ = new_parent; | 716 inner_scope->outer_scope_ = new_parent; |
702 | 717 |
703 new_parent->inner_scope_ = new_parent->sibling_; | 718 new_parent->inner_scope_ = new_parent->sibling_; |
(...skipping 11 matching lines...) Expand all Loading... |
715 last->set_next_unresolved(nullptr); | 730 last->set_next_unresolved(nullptr); |
716 new_parent->unresolved_ = outer_scope_->unresolved_; | 731 new_parent->unresolved_ = outer_scope_->unresolved_; |
717 outer_scope_->unresolved_ = top_unresolved_; | 732 outer_scope_->unresolved_ = top_unresolved_; |
718 } | 733 } |
719 | 734 |
720 // TODO(verwaest): This currently only moves do-expression declared variables | 735 // TODO(verwaest): This currently only moves do-expression declared variables |
721 // in default arguments that weren't already previously declared with the same | 736 // in default arguments that weren't already previously declared with the same |
722 // name in the closure-scope. See | 737 // name in the closure-scope. See |
723 // test/mjsunit/harmony/default-parameter-do-expression.js. | 738 // test/mjsunit/harmony/default-parameter-do-expression.js. |
724 DeclarationScope* outer_closure = outer_scope_->GetClosureScope(); | 739 DeclarationScope* outer_closure = outer_scope_->GetClosureScope(); |
725 for (int i = top_local_; i < outer_closure->locals_.length(); i++) { | 740 |
726 Variable* local = outer_closure->locals_.at(i); | 741 new_parent->locals_.MoveTail(outer_closure->locals(), top_local_); |
| 742 for (Variable* local : new_parent->locals_) { |
727 DCHECK(local->mode() == TEMPORARY || local->mode() == VAR); | 743 DCHECK(local->mode() == TEMPORARY || local->mode() == VAR); |
728 DCHECK_EQ(local->scope(), local->scope()->GetClosureScope()); | 744 DCHECK_EQ(local->scope(), local->scope()->GetClosureScope()); |
729 DCHECK_NE(local->scope(), new_parent); | 745 DCHECK_NE(local->scope(), new_parent); |
730 local->set_scope(new_parent); | 746 local->set_scope(new_parent); |
731 new_parent->AddLocal(local); | |
732 if (local->mode() == VAR) { | 747 if (local->mode() == VAR) { |
733 outer_closure->variables_.Remove(local); | 748 outer_closure->variables_.Remove(local); |
734 new_parent->variables_.Add(new_parent->zone(), local); | 749 new_parent->variables_.Add(new_parent->zone(), local); |
735 } | 750 } |
736 } | 751 } |
737 outer_closure->locals_.Rewind(top_local_); | 752 outer_closure->locals_.Rewind(top_local_); |
738 outer_closure->decls_.Rewind(top_decl_); | 753 outer_closure->decls_.Rewind(top_decl_); |
739 } | 754 } |
740 | 755 |
741 void Scope::ReplaceOuterScope(Scope* outer) { | 756 void Scope::ReplaceOuterScope(Scope* outer) { |
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1231 } | 1246 } |
1232 return non_locals; | 1247 return non_locals; |
1233 } | 1248 } |
1234 | 1249 |
1235 void DeclarationScope::ResetAfterPreparsing(AstValueFactory* ast_value_factory, | 1250 void DeclarationScope::ResetAfterPreparsing(AstValueFactory* ast_value_factory, |
1236 bool aborted) { | 1251 bool aborted) { |
1237 DCHECK(is_function_scope()); | 1252 DCHECK(is_function_scope()); |
1238 | 1253 |
1239 // Reset all non-trivial members. | 1254 // Reset all non-trivial members. |
1240 decls_.Clear(); | 1255 decls_.Clear(); |
1241 locals_.Rewind(0); | 1256 locals_.Clear(); |
1242 sloppy_block_function_map_.Clear(); | 1257 sloppy_block_function_map_.Clear(); |
1243 variables_.Clear(); | 1258 variables_.Clear(); |
1244 // Make sure we won't walk the scope tree from here on. | 1259 // Make sure we won't walk the scope tree from here on. |
1245 inner_scope_ = nullptr; | 1260 inner_scope_ = nullptr; |
1246 unresolved_ = nullptr; | 1261 unresolved_ = nullptr; |
1247 | 1262 |
1248 // TODO(verwaest): We should properly preparse the parameters (no declarations | 1263 // TODO(verwaest): We should properly preparse the parameters (no declarations |
1249 // should be created), and reparse on abort. | 1264 // should be created), and reparse on abort. |
1250 if (aborted) { | 1265 if (aborted) { |
1251 if (!IsArrowFunction(function_kind_)) { | 1266 if (!IsArrowFunction(function_kind_)) { |
1252 DeclareDefaultFunctionVariables(ast_value_factory); | 1267 DeclareDefaultFunctionVariables(ast_value_factory); |
1253 } | 1268 } |
1254 // Recreate declarations for parameters. | 1269 // Recreate declarations for parameters. |
1255 for (int i = 0; i < params_.length(); i++) { | 1270 for (int i = 0; i < params_.length(); i++) { |
1256 Variable* var = params_[i]; | 1271 Variable* var = params_[i]; |
1257 if (var->mode() == TEMPORARY) { | 1272 if (var->mode() == TEMPORARY) { |
1258 locals_.Add(var, zone()); | 1273 // TODO(verwaest): Remove and unfriend DeclarationScope from Variable. |
| 1274 *var->next() = nullptr; |
| 1275 locals_.Add(var); |
1259 } else if (variables_.Lookup(var->raw_name()) == nullptr) { | 1276 } else if (variables_.Lookup(var->raw_name()) == nullptr) { |
| 1277 // TODO(verwaest): Remove and unfriend DeclarationScope from Variable. |
| 1278 *var->next() = nullptr; |
1260 variables_.Add(zone(), var); | 1279 variables_.Add(zone(), var); |
1261 locals_.Add(var, zone()); | 1280 locals_.Add(var); |
1262 } | 1281 } |
1263 } | 1282 } |
1264 } else { | 1283 } else { |
1265 params_.Rewind(0); | 1284 params_.Rewind(0); |
1266 } | 1285 } |
1267 | 1286 |
1268 #ifdef DEBUG | 1287 #ifdef DEBUG |
1269 needs_migration_ = false; | 1288 needs_migration_ = false; |
1270 #endif | 1289 #endif |
1271 | 1290 |
(...skipping 605 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1877 if (var->IsUnallocated() && MustAllocate(var)) { | 1896 if (var->IsUnallocated() && MustAllocate(var)) { |
1878 if (MustAllocateInContext(var)) { | 1897 if (MustAllocateInContext(var)) { |
1879 AllocateHeapSlot(var); | 1898 AllocateHeapSlot(var); |
1880 } else { | 1899 } else { |
1881 AllocateStackSlot(var); | 1900 AllocateStackSlot(var); |
1882 } | 1901 } |
1883 } | 1902 } |
1884 } | 1903 } |
1885 | 1904 |
1886 void Scope::AllocateNonParameterLocalsAndDeclaredGlobals() { | 1905 void Scope::AllocateNonParameterLocalsAndDeclaredGlobals() { |
1887 for (int i = 0; i < locals_.length(); i++) { | 1906 for (Variable* local : locals_) { |
1888 AllocateNonParameterLocal(locals_[i]); | 1907 AllocateNonParameterLocal(local); |
1889 } | 1908 } |
1890 | 1909 |
1891 if (is_declaration_scope()) { | 1910 if (is_declaration_scope()) { |
1892 AsDeclarationScope()->AllocateLocals(); | 1911 AsDeclarationScope()->AllocateLocals(); |
1893 } | 1912 } |
1894 } | 1913 } |
1895 | 1914 |
1896 void DeclarationScope::AllocateLocals() { | 1915 void DeclarationScope::AllocateLocals() { |
1897 // For now, function_ must be allocated at the very end. If it gets | 1916 // For now, function_ must be allocated at the very end. If it gets |
1898 // allocated in the context, it must be the last slot in the context, | 1917 // allocated in the context, it must be the last slot in the context, |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2017 Variable* function = | 2036 Variable* function = |
2018 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; | 2037 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; |
2019 bool is_function_var_in_context = | 2038 bool is_function_var_in_context = |
2020 function != nullptr && function->IsContextSlot(); | 2039 function != nullptr && function->IsContextSlot(); |
2021 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 2040 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
2022 (is_function_var_in_context ? 1 : 0); | 2041 (is_function_var_in_context ? 1 : 0); |
2023 } | 2042 } |
2024 | 2043 |
2025 } // namespace internal | 2044 } // namespace internal |
2026 } // namespace v8 | 2045 } // namespace v8 |
OLD | NEW |