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" |
11 #include "src/bootstrapper.h" | 11 #include "src/bootstrapper.h" |
12 #include "src/messages.h" | 12 #include "src/messages.h" |
13 #include "src/parsing/parse-info.h" | 13 #include "src/parsing/parse-info.h" |
14 | 14 |
15 namespace v8 { | 15 namespace v8 { |
16 namespace internal { | 16 namespace internal { |
17 | 17 |
| 18 namespace { |
| 19 void* kDummyPreParserVariable = reinterpret_cast<void*>(0x1); |
| 20 } // namespace |
| 21 |
18 // ---------------------------------------------------------------------------- | 22 // ---------------------------------------------------------------------------- |
19 // Implementation of LocalsMap | 23 // Implementation of LocalsMap |
20 // | 24 // |
21 // Note: We are storing the handle locations as key values in the hash map. | 25 // Note: We are storing the handle locations as key values in the hash map. |
22 // When inserting a new variable via Declare(), we rely on the fact that | 26 // When inserting a new variable via Declare(), we rely on the fact that |
23 // the handle location remains alive for the duration of that variable | 27 // the handle location remains alive for the duration of that variable |
24 // use. Because a Variable holding a handle with the same location exists | 28 // use. Because a Variable holding a handle with the same location exists |
25 // this is ensured. | 29 // this is ensured. |
26 | 30 |
27 VariableMap::VariableMap(Zone* zone) | 31 VariableMap::VariableMap(Zone* zone) |
(...skipping 14 matching lines...) Expand all Loading... |
42 if (added) *added = p->value == nullptr; | 46 if (added) *added = p->value == nullptr; |
43 if (p->value == nullptr) { | 47 if (p->value == nullptr) { |
44 // The variable has not been declared yet -> insert it. | 48 // The variable has not been declared yet -> insert it. |
45 DCHECK_EQ(name, p->key); | 49 DCHECK_EQ(name, p->key); |
46 p->value = new (zone) Variable(scope, name, mode, kind, initialization_flag, | 50 p->value = new (zone) Variable(scope, name, mode, kind, initialization_flag, |
47 maybe_assigned_flag); | 51 maybe_assigned_flag); |
48 } | 52 } |
49 return reinterpret_cast<Variable*>(p->value); | 53 return reinterpret_cast<Variable*>(p->value); |
50 } | 54 } |
51 | 55 |
| 56 void VariableMap::DeclareName(Zone* zone, const AstRawString* name) { |
| 57 Entry* p = |
| 58 ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(), |
| 59 ZoneAllocationPolicy(zone)); |
| 60 if (p->value == nullptr) { |
| 61 // The variable has not been declared yet -> insert it. |
| 62 DCHECK_EQ(name, p->key); |
| 63 p->value = kDummyPreParserVariable; |
| 64 } |
| 65 } |
| 66 |
52 void VariableMap::Remove(Variable* var) { | 67 void VariableMap::Remove(Variable* var) { |
53 const AstRawString* name = var->raw_name(); | 68 const AstRawString* name = var->raw_name(); |
54 ZoneHashMap::Remove(const_cast<AstRawString*>(name), name->hash()); | 69 ZoneHashMap::Remove(const_cast<AstRawString*>(name), name->hash()); |
55 } | 70 } |
56 | 71 |
57 void VariableMap::Add(Zone* zone, Variable* var) { | 72 void VariableMap::Add(Zone* zone, Variable* var) { |
58 const AstRawString* name = var->raw_name(); | 73 const AstRawString* name = var->raw_name(); |
59 Entry* p = | 74 Entry* p = |
60 ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(), | 75 ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(), |
61 ZoneAllocationPolicy(zone)); | 76 ZoneAllocationPolicy(zone)); |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 force_eager_compilation_ = false; | 271 force_eager_compilation_ = false; |
257 has_arguments_parameter_ = false; | 272 has_arguments_parameter_ = false; |
258 scope_uses_super_property_ = false; | 273 scope_uses_super_property_ = false; |
259 has_rest_ = false; | 274 has_rest_ = false; |
260 receiver_ = nullptr; | 275 receiver_ = nullptr; |
261 new_target_ = nullptr; | 276 new_target_ = nullptr; |
262 function_ = nullptr; | 277 function_ = nullptr; |
263 arguments_ = nullptr; | 278 arguments_ = nullptr; |
264 this_function_ = nullptr; | 279 this_function_ = nullptr; |
265 should_eager_compile_ = false; | 280 should_eager_compile_ = false; |
266 is_lazily_parsed_ = false; | 281 was_lazily_parsed_ = false; |
| 282 #ifdef DEBUG |
| 283 DeclarationScope* outer_declaration_scope = |
| 284 outer_scope_ ? outer_scope_->GetDeclarationScope() : nullptr; |
| 285 is_being_lazily_parsed_ = |
| 286 outer_declaration_scope ? outer_declaration_scope->is_being_lazily_parsed_ |
| 287 : false; |
| 288 #endif |
267 } | 289 } |
268 | 290 |
269 void Scope::SetDefaults() { | 291 void Scope::SetDefaults() { |
270 #ifdef DEBUG | 292 #ifdef DEBUG |
271 scope_name_ = nullptr; | 293 scope_name_ = nullptr; |
272 already_resolved_ = false; | 294 already_resolved_ = false; |
273 needs_migration_ = false; | 295 needs_migration_ = false; |
274 #endif | 296 #endif |
275 inner_scope_ = nullptr; | 297 inner_scope_ = nullptr; |
276 sibling_ = nullptr; | 298 sibling_ = nullptr; |
(...skipping 21 matching lines...) Expand all Loading... |
298 bool Scope::HasSimpleParameters() { | 320 bool Scope::HasSimpleParameters() { |
299 DeclarationScope* scope = GetClosureScope(); | 321 DeclarationScope* scope = GetClosureScope(); |
300 return !scope->is_function_scope() || scope->has_simple_parameters(); | 322 return !scope->is_function_scope() || scope->has_simple_parameters(); |
301 } | 323 } |
302 | 324 |
303 bool DeclarationScope::ShouldEagerCompile() const { | 325 bool DeclarationScope::ShouldEagerCompile() const { |
304 return force_eager_compilation_ || should_eager_compile_; | 326 return force_eager_compilation_ || should_eager_compile_; |
305 } | 327 } |
306 | 328 |
307 void DeclarationScope::set_should_eager_compile() { | 329 void DeclarationScope::set_should_eager_compile() { |
308 should_eager_compile_ = !is_lazily_parsed_; | 330 should_eager_compile_ = !was_lazily_parsed_; |
309 } | 331 } |
310 | 332 |
311 void DeclarationScope::set_asm_module() { | 333 void DeclarationScope::set_asm_module() { |
312 asm_module_ = true; | 334 asm_module_ = true; |
313 // Mark any existing inner function scopes as asm function scopes. | 335 // Mark any existing inner function scopes as asm function scopes. |
314 for (Scope* inner = inner_scope_; inner != nullptr; inner = inner->sibling_) { | 336 for (Scope* inner = inner_scope_; inner != nullptr; inner = inner->sibling_) { |
315 if (inner->is_function_scope()) { | 337 if (inner->is_function_scope()) { |
316 inner->AsDeclarationScope()->set_asm_function(); | 338 inner->AsDeclarationScope()->set_asm_function(); |
317 } | 339 } |
318 } | 340 } |
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
859 return NULL; | 881 return NULL; |
860 } | 882 } |
861 | 883 |
862 Variable* DeclarationScope::DeclareParameter( | 884 Variable* DeclarationScope::DeclareParameter( |
863 const AstRawString* name, VariableMode mode, bool is_optional, bool is_rest, | 885 const AstRawString* name, VariableMode mode, bool is_optional, bool is_rest, |
864 bool* is_duplicate, AstValueFactory* ast_value_factory) { | 886 bool* is_duplicate, AstValueFactory* ast_value_factory) { |
865 DCHECK(!already_resolved_); | 887 DCHECK(!already_resolved_); |
866 DCHECK(is_function_scope() || is_module_scope()); | 888 DCHECK(is_function_scope() || is_module_scope()); |
867 DCHECK(!has_rest_); | 889 DCHECK(!has_rest_); |
868 DCHECK(!is_optional || !is_rest); | 890 DCHECK(!is_optional || !is_rest); |
| 891 DCHECK(!is_being_lazily_parsed_); |
| 892 DCHECK(!was_lazily_parsed_); |
869 Variable* var; | 893 Variable* var; |
870 if (mode == TEMPORARY) { | 894 if (mode == TEMPORARY) { |
871 var = NewTemporary(name); | 895 var = NewTemporary(name); |
872 } else { | 896 } else { |
873 var = Declare(zone(), name, mode, NORMAL_VARIABLE, kCreatedInitialized); | 897 var = Declare(zone(), name, mode, NORMAL_VARIABLE, kCreatedInitialized); |
874 // TODO(wingo): Avoid O(n^2) check. | 898 // TODO(wingo): Avoid O(n^2) check. |
875 *is_duplicate = IsDeclaredParameter(name); | 899 *is_duplicate = IsDeclaredParameter(name); |
876 } | 900 } |
877 has_rest_ = is_rest; | 901 has_rest_ = is_rest; |
878 params_.Add(var, zone()); | 902 params_.Add(var, zone()); |
879 if (name == ast_value_factory->arguments_string()) { | 903 if (name == ast_value_factory->arguments_string()) { |
880 has_arguments_parameter_ = true; | 904 has_arguments_parameter_ = true; |
881 } | 905 } |
882 return var; | 906 return var; |
883 } | 907 } |
884 | 908 |
885 Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode, | 909 Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode, |
886 InitializationFlag init_flag, VariableKind kind, | 910 InitializationFlag init_flag, VariableKind kind, |
887 MaybeAssignedFlag maybe_assigned_flag) { | 911 MaybeAssignedFlag maybe_assigned_flag) { |
888 DCHECK(!already_resolved_); | 912 DCHECK(!already_resolved_); |
889 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are | 913 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are |
890 // introduced during variable allocation, and TEMPORARY variables are | 914 // introduced during variable allocation, and TEMPORARY variables are |
891 // allocated via NewTemporary(). | 915 // allocated via NewTemporary(). |
892 DCHECK(IsDeclaredVariableMode(mode)); | 916 DCHECK(IsDeclaredVariableMode(mode)); |
| 917 DCHECK(!GetDeclarationScope()->is_being_lazily_parsed()); |
| 918 DCHECK(!GetDeclarationScope()->was_lazily_parsed()); |
893 return Declare(zone(), name, mode, kind, init_flag, maybe_assigned_flag); | 919 return Declare(zone(), name, mode, kind, init_flag, maybe_assigned_flag); |
894 } | 920 } |
895 | 921 |
896 Variable* Scope::DeclareVariable( | 922 Variable* Scope::DeclareVariable( |
897 Declaration* declaration, VariableMode mode, InitializationFlag init, | 923 Declaration* declaration, VariableMode mode, InitializationFlag init, |
898 bool allow_harmony_restrictive_generators, | 924 bool allow_harmony_restrictive_generators, |
899 bool* sloppy_mode_block_scope_function_redefinition, bool* ok) { | 925 bool* sloppy_mode_block_scope_function_redefinition, bool* ok) { |
900 DCHECK(IsDeclaredVariableMode(mode)); | 926 DCHECK(IsDeclaredVariableMode(mode)); |
901 DCHECK(!already_resolved_); | 927 DCHECK(!already_resolved_); |
| 928 DCHECK(!GetDeclarationScope()->is_being_lazily_parsed()); |
| 929 DCHECK(!GetDeclarationScope()->was_lazily_parsed()); |
902 | 930 |
903 if (mode == VAR && !is_declaration_scope()) { | 931 if (mode == VAR && !is_declaration_scope()) { |
904 return GetDeclarationScope()->DeclareVariable( | 932 return GetDeclarationScope()->DeclareVariable( |
905 declaration, mode, init, allow_harmony_restrictive_generators, | 933 declaration, mode, init, allow_harmony_restrictive_generators, |
906 sloppy_mode_block_scope_function_redefinition, ok); | 934 sloppy_mode_block_scope_function_redefinition, ok); |
907 } | 935 } |
908 DCHECK(!is_catch_scope()); | 936 DCHECK(!is_catch_scope()); |
909 DCHECK(!is_with_scope()); | 937 DCHECK(!is_with_scope()); |
910 DCHECK(is_declaration_scope() || | 938 DCHECK(is_declaration_scope() || |
911 (IsLexicalVariableMode(mode) && is_block_scope())); | 939 (IsLexicalVariableMode(mode) && is_block_scope())); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
990 // | 1018 // |
991 // This will lead to multiple declaration nodes for the | 1019 // This will lead to multiple declaration nodes for the |
992 // same variable if it is declared several times. This is not a | 1020 // same variable if it is declared several times. This is not a |
993 // semantic issue, but it may be a performance issue since it may | 1021 // semantic issue, but it may be a performance issue since it may |
994 // lead to repeated DeclareEvalVar or DeclareEvalFunction calls. | 1022 // lead to repeated DeclareEvalVar or DeclareEvalFunction calls. |
995 decls_.Add(declaration); | 1023 decls_.Add(declaration); |
996 proxy->BindTo(var); | 1024 proxy->BindTo(var); |
997 return var; | 1025 return var; |
998 } | 1026 } |
999 | 1027 |
| 1028 void Scope::DeclareVariableName(const AstRawString* name, VariableMode mode) { |
| 1029 DCHECK(IsDeclaredVariableMode(mode)); |
| 1030 DCHECK(!already_resolved_); |
| 1031 DCHECK(GetDeclarationScope()->is_being_lazily_parsed()); |
| 1032 |
| 1033 if (mode == VAR && !is_declaration_scope()) { |
| 1034 return GetDeclarationScope()->DeclareVariableName(name, mode); |
| 1035 } |
| 1036 DCHECK(!is_catch_scope()); |
| 1037 DCHECK(!is_with_scope()); |
| 1038 DCHECK(!is_eval_scope()); |
| 1039 DCHECK(is_declaration_scope() || |
| 1040 (IsLexicalVariableMode(mode) && is_block_scope())); |
| 1041 |
| 1042 // Declare the variable in the declaration scope. |
| 1043 if (LookupLocal(name) == nullptr) { |
| 1044 variables_.DeclareName(zone(), name); |
| 1045 } |
| 1046 } |
| 1047 |
1000 VariableProxy* Scope::NewUnresolved(AstNodeFactory* factory, | 1048 VariableProxy* Scope::NewUnresolved(AstNodeFactory* factory, |
1001 const AstRawString* name, | 1049 const AstRawString* name, |
1002 int start_position, VariableKind kind) { | 1050 int start_position, VariableKind kind) { |
1003 // Note that we must not share the unresolved variables with | 1051 // Note that we must not share the unresolved variables with |
1004 // the same name because they may be removed selectively via | 1052 // the same name because they may be removed selectively via |
1005 // RemoveUnresolved(). | 1053 // RemoveUnresolved(). |
1006 DCHECK(!already_resolved_); | 1054 DCHECK(!already_resolved_); |
1007 DCHECK_EQ(factory->zone(), zone()); | 1055 DCHECK_EQ(factory->zone(), zone()); |
1008 VariableProxy* proxy = factory->NewVariableProxy(name, kind, start_position); | 1056 VariableProxy* proxy = factory->NewVariableProxy(name, kind, start_position); |
1009 proxy->set_next_unresolved(unresolved_); | 1057 proxy->set_next_unresolved(unresolved_); |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1264 Scope* Scope::GetOuterScopeWithContext() { | 1312 Scope* Scope::GetOuterScopeWithContext() { |
1265 Scope* scope = outer_scope_; | 1313 Scope* scope = outer_scope_; |
1266 while (scope && !scope->NeedsContext()) { | 1314 while (scope && !scope->NeedsContext()) { |
1267 scope = scope->outer_scope(); | 1315 scope = scope->outer_scope(); |
1268 } | 1316 } |
1269 return scope; | 1317 return scope; |
1270 } | 1318 } |
1271 | 1319 |
1272 Handle<StringSet> DeclarationScope::CollectNonLocals( | 1320 Handle<StringSet> DeclarationScope::CollectNonLocals( |
1273 ParseInfo* info, Handle<StringSet> non_locals) { | 1321 ParseInfo* info, Handle<StringSet> non_locals) { |
1274 VariableProxy* free_variables = FetchFreeVariables(this, true, info); | 1322 VariableProxy* free_variables = FetchFreeVariables(this, info); |
1275 for (VariableProxy* proxy = free_variables; proxy != nullptr; | 1323 for (VariableProxy* proxy = free_variables; proxy != nullptr; |
1276 proxy = proxy->next_unresolved()) { | 1324 proxy = proxy->next_unresolved()) { |
1277 non_locals = StringSet::Add(non_locals, proxy->name()); | 1325 non_locals = StringSet::Add(non_locals, proxy->name()); |
1278 } | 1326 } |
1279 return non_locals; | 1327 return non_locals; |
1280 } | 1328 } |
1281 | 1329 |
1282 void DeclarationScope::ResetAfterPreparsing(AstValueFactory* ast_value_factory, | 1330 void DeclarationScope::ResetAfterPreparsing(AstValueFactory* ast_value_factory, |
1283 bool aborted) { | 1331 bool aborted) { |
1284 DCHECK(is_function_scope()); | 1332 DCHECK(is_function_scope()); |
(...skipping 15 matching lines...) Expand all Loading... |
1300 } | 1348 } |
1301 } else { | 1349 } else { |
1302 // Make sure this scope isn't used for allocation anymore. | 1350 // Make sure this scope isn't used for allocation anymore. |
1303 zone_ = nullptr; | 1351 zone_ = nullptr; |
1304 variables_.Invalidate(); | 1352 variables_.Invalidate(); |
1305 sloppy_block_function_map_.Invalidate(); | 1353 sloppy_block_function_map_.Invalidate(); |
1306 } | 1354 } |
1307 | 1355 |
1308 #ifdef DEBUG | 1356 #ifdef DEBUG |
1309 needs_migration_ = false; | 1357 needs_migration_ = false; |
| 1358 is_being_lazily_parsed_ = false; |
1310 #endif | 1359 #endif |
1311 | 1360 |
1312 is_lazily_parsed_ = !aborted; | 1361 was_lazily_parsed_ = !aborted; |
1313 } | 1362 } |
1314 | 1363 |
1315 void DeclarationScope::AnalyzePartially(AstNodeFactory* ast_node_factory) { | 1364 void DeclarationScope::AnalyzePartially(AstNodeFactory* ast_node_factory) { |
1316 DCHECK(!force_eager_compilation_); | 1365 DCHECK(!force_eager_compilation_); |
1317 VariableProxy* unresolved = nullptr; | 1366 VariableProxy* unresolved = nullptr; |
1318 | 1367 |
1319 if (!outer_scope_->is_script_scope()) { | 1368 if (!outer_scope_->is_script_scope()) { |
1320 // Try to resolve unresolved variables for this Scope and migrate those | 1369 // Try to resolve unresolved variables for this Scope and migrate those |
1321 // which cannot be resolved inside. It doesn't make sense to try to resolve | 1370 // which cannot be resolved inside. It doesn't make sense to try to resolve |
1322 // them in the outer Scopes here, because they are incomplete. | 1371 // them in the outer Scopes here, because they are incomplete. |
1323 for (VariableProxy* proxy = | 1372 for (VariableProxy* proxy = FetchFreeVariables(this); proxy != nullptr; |
1324 FetchFreeVariables(this, !FLAG_lazy_inner_functions); | 1373 proxy = proxy->next_unresolved()) { |
1325 proxy != nullptr; proxy = proxy->next_unresolved()) { | |
1326 DCHECK(!proxy->is_resolved()); | 1374 DCHECK(!proxy->is_resolved()); |
1327 VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy); | 1375 VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy); |
1328 copy->set_next_unresolved(unresolved); | 1376 copy->set_next_unresolved(unresolved); |
1329 unresolved = copy; | 1377 unresolved = copy; |
1330 } | 1378 } |
1331 | 1379 |
1332 // Clear arguments_ if unused. This is used as a signal for optimization. | 1380 // Clear arguments_ if unused. This is used as a signal for optimization. |
1333 if (arguments_ != nullptr && | 1381 if (arguments_ != nullptr && |
1334 !(MustAllocate(arguments_) && !has_arguments_parameter_)) { | 1382 !(MustAllocate(arguments_) && !has_arguments_parameter_)) { |
1335 arguments_ = nullptr; | 1383 arguments_ = nullptr; |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1483 } | 1531 } |
1484 if (IsAsmModule()) Indent(n1, "// scope is an asm module\n"); | 1532 if (IsAsmModule()) Indent(n1, "// scope is an asm module\n"); |
1485 if (IsAsmFunction()) Indent(n1, "// scope is an asm function\n"); | 1533 if (IsAsmFunction()) Indent(n1, "// scope is an asm function\n"); |
1486 if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n"); | 1534 if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n"); |
1487 if (is_declaration_scope() && AsDeclarationScope()->uses_super_property()) { | 1535 if (is_declaration_scope() && AsDeclarationScope()->uses_super_property()) { |
1488 Indent(n1, "// scope uses 'super' property\n"); | 1536 Indent(n1, "// scope uses 'super' property\n"); |
1489 } | 1537 } |
1490 if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n"); | 1538 if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n"); |
1491 if (is_declaration_scope()) { | 1539 if (is_declaration_scope()) { |
1492 DeclarationScope* scope = AsDeclarationScope(); | 1540 DeclarationScope* scope = AsDeclarationScope(); |
1493 if (scope->is_lazily_parsed()) Indent(n1, "// lazily parsed\n"); | 1541 if (scope->was_lazily_parsed()) Indent(n1, "// lazily parsed\n"); |
1494 if (scope->ShouldEagerCompile()) Indent(n1, "// will be compiled\n"); | 1542 if (scope->ShouldEagerCompile()) Indent(n1, "// will be compiled\n"); |
1495 } | 1543 } |
1496 if (num_stack_slots_ > 0) { | 1544 if (num_stack_slots_ > 0) { |
1497 Indent(n1, "// "); | 1545 Indent(n1, "// "); |
1498 PrintF("%d stack slots\n", num_stack_slots_); | 1546 PrintF("%d stack slots\n", num_stack_slots_); |
1499 } | 1547 } |
1500 if (num_heap_slots_ > 0) { | 1548 if (num_heap_slots_ > 0) { |
1501 Indent(n1, "// "); | 1549 Indent(n1, "// "); |
1502 PrintF("%d heap slots\n", num_heap_slots_); | 1550 PrintF("%d heap slots\n", num_heap_slots_); |
1503 } | 1551 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1536 } | 1584 } |
1537 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 1585 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
1538 scope->CheckScopePositions(); | 1586 scope->CheckScopePositions(); |
1539 } | 1587 } |
1540 } | 1588 } |
1541 | 1589 |
1542 void Scope::CheckZones() { | 1590 void Scope::CheckZones() { |
1543 DCHECK(!needs_migration_); | 1591 DCHECK(!needs_migration_); |
1544 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 1592 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
1545 if (scope->is_declaration_scope() && | 1593 if (scope->is_declaration_scope() && |
1546 scope->AsDeclarationScope()->is_lazily_parsed()) { | 1594 scope->AsDeclarationScope()->was_lazily_parsed()) { |
1547 DCHECK_NULL(scope->zone()); | 1595 DCHECK_NULL(scope->zone()); |
1548 DCHECK_NULL(scope->inner_scope_); | 1596 DCHECK_NULL(scope->inner_scope_); |
1549 continue; | 1597 continue; |
1550 } | 1598 } |
1551 CHECK_EQ(scope->zone(), zone()); | 1599 CHECK_EQ(scope->zone(), zone()); |
1552 scope->CheckZones(); | 1600 scope->CheckZones(); |
1553 } | 1601 } |
1554 } | 1602 } |
1555 #endif // DEBUG | 1603 #endif // DEBUG |
1556 | 1604 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1592 NORMAL_VARIABLE); | 1640 NORMAL_VARIABLE); |
1593 } | 1641 } |
1594 | 1642 |
1595 DCHECK(!is_script_scope()); | 1643 DCHECK(!is_script_scope()); |
1596 | 1644 |
1597 var = outer_scope_->LookupRecursive(proxy, outer_scope_end); | 1645 var = outer_scope_->LookupRecursive(proxy, outer_scope_end); |
1598 | 1646 |
1599 // The variable could not be resolved statically. | 1647 // The variable could not be resolved statically. |
1600 if (var == nullptr) return var; | 1648 if (var == nullptr) return var; |
1601 | 1649 |
| 1650 // TODO(marja): Separate LookupRecursive for preparsed scopes better. |
| 1651 if (var == kDummyPreParserVariable) { |
| 1652 DCHECK(GetDeclarationScope()->is_being_lazily_parsed()); |
| 1653 DCHECK(FLAG_lazy_inner_functions); |
| 1654 return var; |
| 1655 } |
| 1656 |
1602 if (is_function_scope() && !var->is_dynamic()) { | 1657 if (is_function_scope() && !var->is_dynamic()) { |
1603 var->ForceContextAllocation(); | 1658 var->ForceContextAllocation(); |
1604 } | 1659 } |
1605 // "this" can't be shadowed by "eval"-introduced bindings or by "with" | 1660 // "this" can't be shadowed by "eval"-introduced bindings or by "with" |
1606 // scopes. | 1661 // scopes. |
1607 // TODO(wingo): There are other variables in this category; add them. | 1662 // TODO(wingo): There are other variables in this category; add them. |
1608 if (var->is_this()) return var; | 1663 if (var->is_this()) return var; |
1609 | 1664 |
1610 if (is_with_scope()) { | 1665 if (is_with_scope()) { |
1611 // The current scope is a with scope, so the variable binding can not be | 1666 // The current scope is a with scope, so the variable binding can not be |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1731 if (proxy->is_assigned()) var->set_maybe_assigned(); | 1786 if (proxy->is_assigned()) var->set_maybe_assigned(); |
1732 if (AccessNeedsHoleCheck(var, proxy, this)) proxy->set_needs_hole_check(); | 1787 if (AccessNeedsHoleCheck(var, proxy, this)) proxy->set_needs_hole_check(); |
1733 proxy->BindTo(var); | 1788 proxy->BindTo(var); |
1734 } | 1789 } |
1735 | 1790 |
1736 void Scope::ResolveVariablesRecursively(ParseInfo* info) { | 1791 void Scope::ResolveVariablesRecursively(ParseInfo* info) { |
1737 DCHECK(info->script_scope()->is_script_scope()); | 1792 DCHECK(info->script_scope()->is_script_scope()); |
1738 // Lazy parsed declaration scopes are already partially analyzed. If there are | 1793 // Lazy parsed declaration scopes are already partially analyzed. If there are |
1739 // unresolved references remaining, they just need to be resolved in outer | 1794 // unresolved references remaining, they just need to be resolved in outer |
1740 // scopes. | 1795 // scopes. |
1741 if (is_declaration_scope() && AsDeclarationScope()->is_lazily_parsed()) { | 1796 if (is_declaration_scope() && AsDeclarationScope()->was_lazily_parsed()) { |
1742 DCHECK(variables_.occupancy() == 0); | 1797 DCHECK(variables_.occupancy() == 0); |
1743 for (VariableProxy* proxy = unresolved_; proxy != nullptr; | 1798 for (VariableProxy* proxy = unresolved_; proxy != nullptr; |
1744 proxy = proxy->next_unresolved()) { | 1799 proxy = proxy->next_unresolved()) { |
1745 Variable* var = outer_scope()->LookupRecursive(proxy, nullptr); | 1800 Variable* var = outer_scope()->LookupRecursive(proxy, nullptr); |
1746 if (!var->is_dynamic()) { | 1801 if (!var->is_dynamic()) { |
1747 var->set_is_used(); | 1802 var->set_is_used(); |
1748 var->ForceContextAllocation(); | 1803 var->ForceContextAllocation(); |
1749 if (proxy->is_assigned()) var->set_maybe_assigned(); | 1804 if (proxy->is_assigned()) var->set_maybe_assigned(); |
1750 } | 1805 } |
1751 } | 1806 } |
1752 } else { | 1807 } else { |
1753 // Resolve unresolved variables for this scope. | 1808 // Resolve unresolved variables for this scope. |
1754 for (VariableProxy* proxy = unresolved_; proxy != nullptr; | 1809 for (VariableProxy* proxy = unresolved_; proxy != nullptr; |
1755 proxy = proxy->next_unresolved()) { | 1810 proxy = proxy->next_unresolved()) { |
1756 ResolveVariable(info, proxy); | 1811 ResolveVariable(info, proxy); |
1757 } | 1812 } |
1758 | 1813 |
1759 // Resolve unresolved variables for inner scopes. | 1814 // Resolve unresolved variables for inner scopes. |
1760 for (Scope* scope = inner_scope_; scope != nullptr; | 1815 for (Scope* scope = inner_scope_; scope != nullptr; |
1761 scope = scope->sibling_) { | 1816 scope = scope->sibling_) { |
1762 scope->ResolveVariablesRecursively(info); | 1817 scope->ResolveVariablesRecursively(info); |
1763 } | 1818 } |
1764 } | 1819 } |
1765 } | 1820 } |
1766 | 1821 |
1767 VariableProxy* Scope::FetchFreeVariables(DeclarationScope* max_outer_scope, | 1822 VariableProxy* Scope::FetchFreeVariables(DeclarationScope* max_outer_scope, |
1768 bool try_to_resolve, ParseInfo* info, | 1823 ParseInfo* info, |
1769 VariableProxy* stack) { | 1824 VariableProxy* stack) { |
1770 // Lazy parsed declaration scopes are already partially analyzed. If there are | 1825 // Lazy parsed declaration scopes are already partially analyzed. If there are |
1771 // unresolved references remaining, they just need to be resolved in outer | 1826 // unresolved references remaining, they just need to be resolved in outer |
1772 // scopes. | 1827 // scopes. |
1773 Scope* lookup = | 1828 Scope* lookup = |
1774 is_declaration_scope() && AsDeclarationScope()->is_lazily_parsed() | 1829 is_declaration_scope() && AsDeclarationScope()->was_lazily_parsed() |
1775 ? outer_scope() | 1830 ? outer_scope() |
1776 : this; | 1831 : this; |
1777 for (VariableProxy *proxy = unresolved_, *next = nullptr; proxy != nullptr; | 1832 for (VariableProxy *proxy = unresolved_, *next = nullptr; proxy != nullptr; |
1778 proxy = next) { | 1833 proxy = next) { |
1779 next = proxy->next_unresolved(); | 1834 next = proxy->next_unresolved(); |
1780 DCHECK(!proxy->is_resolved()); | 1835 DCHECK(!proxy->is_resolved()); |
1781 Variable* var = nullptr; | 1836 Variable* var = |
1782 if (try_to_resolve) { | 1837 lookup->LookupRecursive(proxy, max_outer_scope->outer_scope()); |
1783 var = lookup->LookupRecursive(proxy, max_outer_scope->outer_scope()); | |
1784 } | |
1785 if (var == nullptr) { | 1838 if (var == nullptr) { |
1786 proxy->set_next_unresolved(stack); | 1839 proxy->set_next_unresolved(stack); |
1787 stack = proxy; | 1840 stack = proxy; |
1788 } else if (info != nullptr) { | 1841 } else if (var != kDummyPreParserVariable) { |
1789 // In this case we need to leave scopes in a way that they can be | 1842 if (info != nullptr) { |
1790 // allocated. If we resolved variables from lazy parsed scopes, we need to | 1843 // In this case we need to leave scopes in a way that they can be |
1791 // context allocate the var. | 1844 // allocated. If we resolved variables from lazy parsed scopes, we need |
1792 ResolveTo(info, proxy, var); | 1845 // to context allocate the var. |
1793 if (!var->is_dynamic() && lookup != this) var->ForceContextAllocation(); | 1846 ResolveTo(info, proxy, var); |
1794 } else { | 1847 if (!var->is_dynamic() && lookup != this) var->ForceContextAllocation(); |
1795 var->set_is_used(); | 1848 } else { |
| 1849 var->set_is_used(); |
| 1850 } |
1796 } | 1851 } |
1797 } | 1852 } |
1798 | 1853 |
1799 // Clear unresolved_ as it's in an inconsistent state. | 1854 // Clear unresolved_ as it's in an inconsistent state. |
1800 unresolved_ = nullptr; | 1855 unresolved_ = nullptr; |
1801 | 1856 |
1802 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 1857 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
1803 stack = | 1858 stack = scope->FetchFreeVariables(max_outer_scope, info, stack); |
1804 scope->FetchFreeVariables(max_outer_scope, try_to_resolve, info, stack); | |
1805 } | 1859 } |
1806 | 1860 |
1807 return stack; | 1861 return stack; |
1808 } | 1862 } |
1809 | 1863 |
1810 bool Scope::MustAllocate(Variable* var) { | 1864 bool Scope::MustAllocate(Variable* var) { |
1811 DCHECK(var->location() != VariableLocation::MODULE); | 1865 DCHECK(var->location() != VariableLocation::MODULE); |
1812 // Give var a read/write use if there is a chance it might be accessed | 1866 // Give var a read/write use if there is a chance it might be accessed |
1813 // via an eval() call. This is only possible if the variable has a | 1867 // via an eval() call. This is only possible if the variable has a |
1814 // visible name. | 1868 // visible name. |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1975 Variable* var = LookupLocal(it.first); | 2029 Variable* var = LookupLocal(it.first); |
1976 var->AllocateTo(VariableLocation::MODULE, it.second->cell_index); | 2030 var->AllocateTo(VariableLocation::MODULE, it.second->cell_index); |
1977 DCHECK(var->IsExport()); | 2031 DCHECK(var->IsExport()); |
1978 } | 2032 } |
1979 } | 2033 } |
1980 | 2034 |
1981 void Scope::AllocateVariablesRecursively() { | 2035 void Scope::AllocateVariablesRecursively() { |
1982 DCHECK(!already_resolved_); | 2036 DCHECK(!already_resolved_); |
1983 DCHECK_EQ(0, num_stack_slots_); | 2037 DCHECK_EQ(0, num_stack_slots_); |
1984 // Don't allocate variables of preparsed scopes. | 2038 // Don't allocate variables of preparsed scopes. |
1985 if (is_declaration_scope() && AsDeclarationScope()->is_lazily_parsed()) { | 2039 if (is_declaration_scope() && AsDeclarationScope()->was_lazily_parsed()) { |
1986 return; | 2040 return; |
1987 } | 2041 } |
1988 | 2042 |
1989 // Allocate variables for inner scopes. | 2043 // Allocate variables for inner scopes. |
1990 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 2044 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
1991 scope->AllocateVariablesRecursively(); | 2045 scope->AllocateVariablesRecursively(); |
1992 } | 2046 } |
1993 | 2047 |
1994 DCHECK(!already_resolved_); | 2048 DCHECK(!already_resolved_); |
1995 DCHECK_EQ(Context::MIN_CONTEXT_SLOTS, num_heap_slots_); | 2049 DCHECK_EQ(Context::MIN_CONTEXT_SLOTS, num_heap_slots_); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2069 Variable* function = | 2123 Variable* function = |
2070 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; | 2124 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; |
2071 bool is_function_var_in_context = | 2125 bool is_function_var_in_context = |
2072 function != nullptr && function->IsContextSlot(); | 2126 function != nullptr && function->IsContextSlot(); |
2073 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 2127 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
2074 (is_function_var_in_context ? 1 : 0); | 2128 (is_function_var_in_context ? 1 : 0); |
2075 } | 2129 } |
2076 | 2130 |
2077 } // namespace internal | 2131 } // namespace internal |
2078 } // namespace v8 | 2132 } // namespace v8 |
OLD | NEW |