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/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
663 MaybeAssignedFlag maybe_assigned_flag) { | 663 MaybeAssignedFlag maybe_assigned_flag) { |
664 DCHECK(!already_resolved()); | 664 DCHECK(!already_resolved()); |
665 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are | 665 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are |
666 // introduced during variable allocation, and TEMPORARY variables are | 666 // introduced during variable allocation, and TEMPORARY variables are |
667 // allocated via NewTemporary(). | 667 // allocated via NewTemporary(). |
668 DCHECK(IsDeclaredVariableMode(mode)); | 668 DCHECK(IsDeclaredVariableMode(mode)); |
669 return variables_.Declare(zone(), this, name, mode, kind, init_flag, | 669 return variables_.Declare(zone(), this, name, mode, kind, init_flag, |
670 maybe_assigned_flag); | 670 maybe_assigned_flag); |
671 } | 671 } |
672 | 672 |
673 Variable* DeclarationScope::DeclareDynamicGlobal(const AstRawString* name) { | 673 Variable* DeclarationScope::DeclareDynamicGlobal(const AstRawString* name, |
| 674 Variable::Kind kind) { |
674 DCHECK(is_script_scope()); | 675 DCHECK(is_script_scope()); |
675 return variables_.Declare(zone(), this, name, DYNAMIC_GLOBAL, | 676 return variables_.Declare(zone(), this, name, DYNAMIC_GLOBAL, kind, |
676 Variable::NORMAL, kCreatedInitialized); | 677 kCreatedInitialized); |
677 } | 678 } |
678 | 679 |
679 | 680 |
680 bool Scope::RemoveUnresolved(VariableProxy* var) { | 681 bool Scope::RemoveUnresolved(VariableProxy* var) { |
681 if (unresolved_ == var) { | 682 if (unresolved_ == var) { |
682 unresolved_ = var->next_unresolved(); | 683 unresolved_ = var->next_unresolved(); |
683 var->set_next_unresolved(nullptr); | 684 var->set_next_unresolved(nullptr); |
684 return true; | 685 return true; |
685 } | 686 } |
686 VariableProxy* current = unresolved_; | 687 VariableProxy* current = unresolved_; |
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1235 } | 1236 } |
1236 } | 1237 } |
1237 | 1238 |
1238 void Scope::CheckZones() { | 1239 void Scope::CheckZones() { |
1239 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 1240 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
1240 CHECK_EQ(scope->zone(), zone()); | 1241 CHECK_EQ(scope->zone(), zone()); |
1241 } | 1242 } |
1242 } | 1243 } |
1243 #endif // DEBUG | 1244 #endif // DEBUG |
1244 | 1245 |
1245 | 1246 Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode, |
1246 Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) { | 1247 Variable::Kind kind) { |
1247 if (dynamics_ == NULL) dynamics_ = new (zone()) DynamicScopePart(zone()); | 1248 if (dynamics_ == NULL) dynamics_ = new (zone()) DynamicScopePart(zone()); |
1248 VariableMap* map = dynamics_->GetMap(mode); | 1249 VariableMap* map = dynamics_->GetMap(mode); |
1249 Variable* var = map->Lookup(name); | 1250 Variable* var = map->Lookup(name); |
1250 if (var == NULL) { | 1251 if (var == NULL) { |
1251 // Declare a new non-local. | 1252 // Declare a new non-local. |
1252 DCHECK(!IsLexicalVariableMode(mode)); | 1253 DCHECK(!IsLexicalVariableMode(mode)); |
1253 var = map->Declare(zone(), NULL, name, mode, Variable::NORMAL, | 1254 var = map->Declare(zone(), NULL, name, mode, kind, kCreatedInitialized); |
1254 kCreatedInitialized); | |
1255 // Allocate it by giving it a dynamic lookup. | 1255 // Allocate it by giving it a dynamic lookup. |
1256 var->AllocateTo(VariableLocation::LOOKUP, -1); | 1256 var->AllocateTo(VariableLocation::LOOKUP, -1); |
1257 } | 1257 } |
1258 return var; | 1258 return var; |
1259 } | 1259 } |
1260 | 1260 |
1261 Variable* Scope::LookupRecursive(VariableProxy* proxy, | 1261 Variable* Scope::LookupRecursive(VariableProxy* proxy, |
1262 BindingKind* binding_kind, | 1262 BindingKind* binding_kind, |
1263 AstNodeFactory* factory, | 1263 AstNodeFactory* factory, |
1264 Scope* outer_scope_end) { | 1264 Scope* outer_scope_end) { |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1374 name->ToCString().get()); | 1374 name->ToCString().get()); |
1375 } | 1375 } |
1376 VariableLocation location = var->location(); | 1376 VariableLocation location = var->location(); |
1377 CHECK(location == VariableLocation::LOCAL || | 1377 CHECK(location == VariableLocation::LOCAL || |
1378 location == VariableLocation::CONTEXT || | 1378 location == VariableLocation::CONTEXT || |
1379 location == VariableLocation::PARAMETER || | 1379 location == VariableLocation::PARAMETER || |
1380 location == VariableLocation::UNALLOCATED); | 1380 location == VariableLocation::UNALLOCATED); |
1381 } | 1381 } |
1382 #endif | 1382 #endif |
1383 | 1383 |
| 1384 // TODO(verwaest): 'this' should always be declared and found. That way we can |
| 1385 // remove this workaround. |
| 1386 Variable::Kind kind = proxy->is_this() ? Variable::THIS : Variable::NORMAL; |
1384 switch (binding_kind) { | 1387 switch (binding_kind) { |
1385 case BOUND: | 1388 case BOUND: |
1386 break; | 1389 break; |
1387 | 1390 |
1388 case BOUND_EVAL_SHADOWED: | 1391 case BOUND_EVAL_SHADOWED: |
1389 // We either found a variable binding that might be shadowed by eval or | 1392 // We either found a variable binding that might be shadowed by eval or |
1390 // gave up on it (e.g. by encountering a local with the same in the outer | 1393 // gave up on it (e.g. by encountering a local with the same in the outer |
1391 // scope which was not promoted to a context, this can happen if we use | 1394 // scope which was not promoted to a context, this can happen if we use |
1392 // debugger to evaluate arbitrary expressions at a break point). | 1395 // debugger to evaluate arbitrary expressions at a break point). |
1393 if (var->IsGlobalObjectProperty()) { | 1396 if (var->IsGlobalObjectProperty()) { |
1394 var = NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL); | 1397 var = NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL, kind); |
1395 } else if (var->is_dynamic()) { | 1398 } else if (var->is_dynamic()) { |
1396 var = NonLocal(proxy->raw_name(), DYNAMIC); | 1399 var = NonLocal(proxy->raw_name(), DYNAMIC, kind); |
1397 } else { | 1400 } else { |
1398 Variable* invalidated = var; | 1401 Variable* invalidated = var; |
1399 var = NonLocal(proxy->raw_name(), DYNAMIC_LOCAL); | 1402 var = NonLocal(proxy->raw_name(), DYNAMIC_LOCAL, kind); |
1400 var->set_local_if_not_shadowed(invalidated); | 1403 var->set_local_if_not_shadowed(invalidated); |
1401 } | 1404 } |
1402 break; | 1405 break; |
1403 | 1406 |
1404 case UNBOUND: | 1407 case UNBOUND: |
1405 // No binding has been found. Declare a variable on the global object. | 1408 // No binding has been found. Declare a variable on the global object. |
1406 var = info->script_scope()->DeclareDynamicGlobal(proxy->raw_name()); | 1409 var = info->script_scope()->DeclareDynamicGlobal(proxy->raw_name(), kind); |
1407 break; | 1410 break; |
1408 | 1411 |
1409 case UNBOUND_EVAL_SHADOWED: | 1412 case UNBOUND_EVAL_SHADOWED: |
1410 // No binding has been found. But some scope makes a sloppy 'eval' call. | 1413 // No binding has been found. But some scope makes a sloppy 'eval' call. |
1411 var = NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL); | 1414 var = NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL, kind); |
1412 break; | 1415 break; |
1413 | 1416 |
1414 case DYNAMIC_LOOKUP: | 1417 case DYNAMIC_LOOKUP: |
1415 // The variable could not be resolved statically. | 1418 // The variable could not be resolved statically. |
1416 var = NonLocal(proxy->raw_name(), DYNAMIC); | 1419 var = NonLocal(proxy->raw_name(), DYNAMIC, kind); |
1417 break; | 1420 break; |
1418 } | 1421 } |
1419 | 1422 |
1420 DCHECK(var != NULL); | 1423 DCHECK(var != NULL); |
1421 if (proxy->is_assigned()) var->set_maybe_assigned(); | 1424 if (proxy->is_assigned()) var->set_maybe_assigned(); |
1422 | 1425 |
1423 proxy->BindTo(var); | 1426 proxy->BindTo(var); |
1424 } | 1427 } |
1425 | 1428 |
1426 void Scope::ResolveVariablesRecursively(ParseInfo* info, | 1429 void Scope::ResolveVariablesRecursively(ParseInfo* info, |
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1787 function != nullptr && function->IsContextSlot(); | 1790 function != nullptr && function->IsContextSlot(); |
1788 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - | 1791 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - |
1789 (is_function_var_in_context ? 1 : 0); | 1792 (is_function_var_in_context ? 1 : 0); |
1790 } | 1793 } |
1791 | 1794 |
1792 | 1795 |
1793 int Scope::ContextGlobalCount() const { return num_global_slots(); } | 1796 int Scope::ContextGlobalCount() const { return num_global_slots(); } |
1794 | 1797 |
1795 } // namespace internal | 1798 } // namespace internal |
1796 } // namespace v8 | 1799 } // namespace v8 |
OLD | NEW |