Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(88)

Side by Side Diff: src/ast/scopes.cc

Issue 2407163003: PreParser: track variable declarations and parameters (Closed)
Patch Set: test fixes + more tests Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ast/scopes.h ('k') | src/parsing/preparser.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/ast/scopes.h ('k') | src/parsing/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698