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