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

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

Issue 2229373002: Fix CollectNonLocals (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Address offline comment Created 4 years, 4 months 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/debug/debug-scopes.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/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 961 matching lines...) Expand 10 before | Expand all | Expand 10 after
972 972
973 973
974 974
975 Handle<ScopeInfo> Scope::GetScopeInfo(Isolate* isolate) { 975 Handle<ScopeInfo> Scope::GetScopeInfo(Isolate* isolate) {
976 if (scope_info_.is_null()) { 976 if (scope_info_.is_null()) {
977 scope_info_ = ScopeInfo::Create(isolate, zone(), this); 977 scope_info_ = ScopeInfo::Create(isolate, zone(), this);
978 } 978 }
979 return scope_info_; 979 return scope_info_;
980 } 980 }
981 981
982 Handle<StringSet> Scope::CollectNonLocals(Handle<StringSet> non_locals) { 982 Handle<StringSet> DeclarationScope::CollectNonLocals(
983 // Collect non-local variables referenced in the scope. 983 ParseInfo* info, Handle<StringSet> non_locals) {
984 // TODO(yangguo): store non-local variables explicitly if we can no longer 984 VariableProxy* free_variables = FetchFreeVariables(this, info);
985 // rely on unresolved_ to find them. 985 for (VariableProxy* proxy = free_variables; proxy != nullptr;
986 for (VariableProxy* proxy = unresolved_; proxy != nullptr;
987 proxy = proxy->next_unresolved()) { 986 proxy = proxy->next_unresolved()) {
988 if (proxy->is_resolved() && proxy->var()->IsStackAllocated()) continue; 987 non_locals = StringSet::Add(non_locals, proxy->name());
989 Handle<String> name = proxy->name();
990 non_locals = StringSet::Add(non_locals, name);
991 }
992 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
993 non_locals = scope->CollectNonLocals(non_locals);
994 } 988 }
995 return non_locals; 989 return non_locals;
996 } 990 }
997 991
998 void DeclarationScope::AnalyzePartially(DeclarationScope* migrate_to, 992 void DeclarationScope::AnalyzePartially(DeclarationScope* migrate_to,
999 AstNodeFactory* ast_node_factory) { 993 AstNodeFactory* ast_node_factory) {
1000 // Gather info from inner scopes. 994 // Gather info from inner scopes.
1001 PropagateScopeInfo(false); 995 PropagateScopeInfo(false);
1002 996
1003 // Try to resolve unresolved variables for this Scope and migrate those which 997 // Try to resolve unresolved variables for this Scope and migrate those which
1004 // cannot be resolved inside. It doesn't make sense to try to resolve them in 998 // cannot be resolved inside. It doesn't make sense to try to resolve them in
1005 // the outer Scopes here, because they are incomplete. 999 // the outer Scopes here, because they are incomplete.
1006 MigrateUnresolvableLocals(migrate_to, ast_node_factory, this); 1000 for (VariableProxy* proxy = FetchFreeVariables(this); proxy != nullptr;
1001 proxy = proxy->next_unresolved()) {
1002 DCHECK(!proxy->is_resolved());
1003 VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy);
1004 migrate_to->AddUnresolved(copy);
1005 }
1007 1006
1008 // Push scope data up to migrate_to. Note that migrate_to and this Scope 1007 // Push scope data up to migrate_to. Note that migrate_to and this Scope
1009 // describe the same Scope, just in different Zones. 1008 // describe the same Scope, just in different Zones.
1010 PropagateUsageFlagsToScope(migrate_to); 1009 PropagateUsageFlagsToScope(migrate_to);
1011 if (inner_scope_calls_eval_) { 1010 if (inner_scope_calls_eval_) {
1012 migrate_to->inner_scope_calls_eval_ = true; 1011 migrate_to->inner_scope_calls_eval_ = true;
1013 } 1012 }
1014 DCHECK(!force_eager_compilation_); 1013 DCHECK(!force_eager_compilation_);
1015 migrate_to->set_start_position(start_position_); 1014 migrate_to->set_start_position(start_position_);
1016 migrate_to->set_end_position(end_position_); 1015 migrate_to->set_end_position(end_position_);
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
1352 DCHECK(info->script_scope()->is_script_scope()); 1351 DCHECK(info->script_scope()->is_script_scope());
1353 1352
1354 // If the proxy is already resolved there's nothing to do 1353 // If the proxy is already resolved there's nothing to do
1355 // (functions and consts may be resolved by the parser). 1354 // (functions and consts may be resolved by the parser).
1356 if (proxy->is_resolved()) return; 1355 if (proxy->is_resolved()) return;
1357 1356
1358 // Otherwise, try to resolve the variable. 1357 // Otherwise, try to resolve the variable.
1359 BindingKind binding_kind; 1358 BindingKind binding_kind;
1360 Variable* var = LookupRecursive(proxy, &binding_kind, factory); 1359 Variable* var = LookupRecursive(proxy, &binding_kind, factory);
1361 1360
1361 ResolveTo(info, binding_kind, proxy, var);
1362 }
1363
1364 void Scope::ResolveTo(ParseInfo* info, BindingKind binding_kind,
1365 VariableProxy* proxy, Variable* var) {
1362 #ifdef DEBUG 1366 #ifdef DEBUG
1363 if (info->script_is_native()) { 1367 if (info->script_is_native()) {
1364 // To avoid polluting the global object in native scripts 1368 // To avoid polluting the global object in native scripts
1365 // - Variables must not be allocated to the global scope. 1369 // - Variables must not be allocated to the global scope.
1366 CHECK_NOT_NULL(outer_scope()); 1370 CHECK_NOT_NULL(outer_scope());
1367 // - Variables must be bound locally or unallocated. 1371 // - Variables must be bound locally or unallocated.
1368 if (BOUND != binding_kind) { 1372 if (BOUND != binding_kind) {
1369 // The following variable name may be minified. If so, disable 1373 // The following variable name may be minified. If so, disable
1370 // minification in js2c.py for better output. 1374 // minification in js2c.py for better output.
1371 Handle<String> name = proxy->raw_name()->string(); 1375 Handle<String> name = proxy->raw_name()->string();
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1431 proxy = proxy->next_unresolved()) { 1435 proxy = proxy->next_unresolved()) {
1432 ResolveVariable(info, proxy, factory); 1436 ResolveVariable(info, proxy, factory);
1433 } 1437 }
1434 1438
1435 // Resolve unresolved variables for inner scopes. 1439 // Resolve unresolved variables for inner scopes.
1436 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { 1440 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
1437 scope->ResolveVariablesRecursively(info, factory); 1441 scope->ResolveVariablesRecursively(info, factory);
1438 } 1442 }
1439 } 1443 }
1440 1444
1441 void Scope::MigrateUnresolvableLocals(DeclarationScope* migrate_to, 1445 VariableProxy* Scope::FetchFreeVariables(DeclarationScope* max_outer_scope,
1442 AstNodeFactory* ast_node_factory, 1446 ParseInfo* info,
1443 DeclarationScope* max_outer_scope) { 1447 VariableProxy* stack) {
1444 BindingKind binding_kind; 1448 BindingKind binding_kind = BOUND;
1445 for (VariableProxy *proxy = unresolved_, *next = nullptr; proxy != nullptr; 1449 for (VariableProxy *proxy = unresolved_, *next = nullptr; proxy != nullptr;
1446 proxy = next) { 1450 proxy = next) {
1447 next = proxy->next_unresolved(); 1451 next = proxy->next_unresolved();
1452 if (proxy->is_resolved()) continue;
1448 // Note that we pass nullptr as AstNodeFactory: this phase should not create 1453 // Note that we pass nullptr as AstNodeFactory: this phase should not create
1449 // any new AstNodes, since none of the Scopes involved are backed up by 1454 // any new AstNodes, since none of the Scopes involved are backed up by
1450 // ScopeInfo. 1455 // ScopeInfo.
1451 if (LookupRecursive(proxy, &binding_kind, nullptr, max_outer_scope) == 1456 Variable* var =
1452 nullptr) { 1457 LookupRecursive(proxy, &binding_kind, nullptr, max_outer_scope);
1453 // Re-create the VariableProxies in the right Zone and insert them into 1458 // Anything that was bound
1454 // migrate_to. 1459 if (var == nullptr) {
1455 DCHECK(!proxy->is_resolved()); 1460 proxy->set_next_unresolved(stack);
1456 VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy); 1461 stack = proxy;
1457 migrate_to->AddUnresolved(copy); 1462 } else if (info != nullptr) {
1463 DCHECK_NE(UNBOUND, binding_kind);
1464 DCHECK_NE(UNBOUND_EVAL_SHADOWED, binding_kind);
1465 ResolveTo(info, binding_kind, proxy, var);
1458 } 1466 }
1459 } 1467 }
1460 1468
1469 // Clear unresolved_ as it's in an inconsistent state.
1470 unresolved_ = nullptr;
1471
1461 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { 1472 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
1462 scope->MigrateUnresolvableLocals(migrate_to, ast_node_factory, 1473 stack = scope->FetchFreeVariables(max_outer_scope, info, stack);
1463 max_outer_scope);
1464 } 1474 }
1475
1476 return stack;
1465 } 1477 }
1466 1478
1467 void Scope::PropagateScopeInfo(bool outer_scope_calls_sloppy_eval) { 1479 void Scope::PropagateScopeInfo(bool outer_scope_calls_sloppy_eval) {
1468 if (outer_scope_calls_sloppy_eval) { 1480 if (outer_scope_calls_sloppy_eval) {
1469 outer_scope_calls_sloppy_eval_ = true; 1481 outer_scope_calls_sloppy_eval_ = true;
1470 } 1482 }
1471 1483
1472 bool calls_sloppy_eval = 1484 bool calls_sloppy_eval =
1473 this->calls_sloppy_eval() || outer_scope_calls_sloppy_eval_; 1485 this->calls_sloppy_eval() || outer_scope_calls_sloppy_eval_;
1474 for (Scope* inner = inner_scope_; inner != nullptr; inner = inner->sibling_) { 1486 for (Scope* inner = inner_scope_; inner != nullptr; inner = inner->sibling_) {
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
1779 function != NULL && function->proxy()->var()->IsContextSlot(); 1791 function != NULL && function->proxy()->var()->IsContextSlot();
1780 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - 1792 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() -
1781 (is_function_var_in_context ? 1 : 0); 1793 (is_function_var_in_context ? 1 : 0);
1782 } 1794 }
1783 1795
1784 1796
1785 int Scope::ContextGlobalCount() const { return num_global_slots(); } 1797 int Scope::ContextGlobalCount() const { return num_global_slots(); }
1786 1798
1787 } // namespace internal 1799 } // namespace internal
1788 } // namespace v8 1800 } // namespace v8
OLDNEW
« no previous file with comments | « src/ast/scopes.h ('k') | src/debug/debug-scopes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698