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 1234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1245 } | 1245 } |
1246 } | 1246 } |
1247 | 1247 |
1248 void Scope::CheckZones() { | 1248 void Scope::CheckZones() { |
1249 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 1249 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
1250 CHECK_EQ(scope->zone(), zone()); | 1250 CHECK_EQ(scope->zone(), zone()); |
1251 } | 1251 } |
1252 } | 1252 } |
1253 #endif // DEBUG | 1253 #endif // DEBUG |
1254 | 1254 |
1255 Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode, | 1255 Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) { |
1256 Variable::Kind kind) { | |
1257 if (dynamics_ == NULL) dynamics_ = new (zone()) DynamicScopePart(zone()); | 1256 if (dynamics_ == NULL) dynamics_ = new (zone()) DynamicScopePart(zone()); |
1258 VariableMap* map = dynamics_->GetMap(mode); | 1257 VariableMap* map = dynamics_->GetMap(mode); |
1259 Variable* var = map->Lookup(name); | 1258 Variable* var = map->Lookup(name); |
1260 if (var == NULL) { | 1259 if (var == NULL) { |
1261 // Declare a new non-local. | 1260 // Declare a new non-local. |
1262 InitializationFlag init_flag = (mode == VAR) | 1261 InitializationFlag init_flag = (mode == VAR) |
1263 ? kCreatedInitialized : kNeedsInitialization; | 1262 ? kCreatedInitialized : kNeedsInitialization; |
1264 var = map->Declare(zone(), NULL, name, mode, kind, init_flag); | 1263 var = map->Declare(zone(), NULL, name, mode, Variable::NORMAL, init_flag); |
1265 // Allocate it by giving it a dynamic lookup. | 1264 // Allocate it by giving it a dynamic lookup. |
1266 var->AllocateTo(VariableLocation::LOOKUP, -1); | 1265 var->AllocateTo(VariableLocation::LOOKUP, -1); |
1267 } | 1266 } |
1268 return var; | 1267 return var; |
1269 } | 1268 } |
1270 | 1269 |
1271 Variable* Scope::LookupRecursive(VariableProxy* proxy, | 1270 Variable* Scope::LookupRecursive(VariableProxy* proxy, |
1272 BindingKind* binding_kind, | 1271 BindingKind* binding_kind, |
1273 AstNodeFactory* factory, | 1272 AstNodeFactory* factory, |
1274 Scope* max_outer_scope) { | 1273 Scope* max_outer_scope) { |
1275 DCHECK(binding_kind != NULL); | 1274 DCHECK(binding_kind != NULL); |
1276 if (already_resolved() && is_with_scope()) { | 1275 if (already_resolved() && is_with_scope()) { |
1277 // Short-cut: if the scope is deserialized from a scope info, variable | 1276 // Short-cut: if the scope is deserialized from a scope info, variable |
1278 // allocation is already fixed. We can simply return with dynamic lookup. | 1277 // allocation is already fixed. We can simply return with dynamic lookup. |
1279 *binding_kind = DYNAMIC_LOOKUP; | 1278 *binding_kind = DYNAMIC_LOOKUP; |
1280 return NULL; | 1279 return NULL; |
Toon Verwaest
2016/08/11 16:06:15
Doh. This "optimization" breaks the obvious case (
| |
1281 } | 1280 } |
1282 | 1281 |
1283 // Try to find the variable in this scope. | 1282 // Try to find the variable in this scope. |
1284 Variable* var = LookupLocal(proxy->raw_name()); | 1283 Variable* var = LookupLocal(proxy->raw_name()); |
1285 | 1284 |
1286 // We found a variable and we are done. (Even if there is an 'eval' in | 1285 // We found a variable and we are done. (Even if there is an 'eval' in |
1287 // this scope which introduces the same variable again, the resulting | 1286 // this scope which introduces the same variable again, the resulting |
1288 // variable remains the same.) | 1287 // variable remains the same.) |
1289 if (var != NULL) { | 1288 if (var != NULL) { |
1290 *binding_kind = BOUND; | 1289 *binding_kind = BOUND; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1378 name->ToCString().get()); | 1377 name->ToCString().get()); |
1379 } | 1378 } |
1380 VariableLocation location = var->location(); | 1379 VariableLocation location = var->location(); |
1381 CHECK(location == VariableLocation::LOCAL || | 1380 CHECK(location == VariableLocation::LOCAL || |
1382 location == VariableLocation::CONTEXT || | 1381 location == VariableLocation::CONTEXT || |
1383 location == VariableLocation::PARAMETER || | 1382 location == VariableLocation::PARAMETER || |
1384 location == VariableLocation::UNALLOCATED); | 1383 location == VariableLocation::UNALLOCATED); |
1385 } | 1384 } |
1386 #endif | 1385 #endif |
1387 | 1386 |
1388 // TODO(verwaest): 'this' should always be declared and found. That way we can | |
1389 // remove this workaround. | |
1390 Variable::Kind kind = proxy->is_this() ? Variable::THIS : Variable::NORMAL; | |
1391 switch (binding_kind) { | 1387 switch (binding_kind) { |
1392 case BOUND: | 1388 case BOUND: |
1393 break; | 1389 break; |
1394 | 1390 |
1395 case BOUND_EVAL_SHADOWED: | 1391 case BOUND_EVAL_SHADOWED: |
1396 // 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 |
1397 // 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 |
1398 // 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 |
1399 // debugger to evaluate arbitrary expressions at a break point). | 1395 // debugger to evaluate arbitrary expressions at a break point). |
1400 if (var->IsGlobalObjectProperty()) { | 1396 if (var->IsGlobalObjectProperty()) { |
1401 var = NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL, kind); | 1397 var = NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL); |
1402 } else if (var->is_dynamic()) { | 1398 } else if (var->is_dynamic()) { |
1403 var = NonLocal(proxy->raw_name(), DYNAMIC, kind); | 1399 var = NonLocal(proxy->raw_name(), DYNAMIC); |
1404 } else { | 1400 } else { |
1405 Variable* invalidated = var; | 1401 Variable* invalidated = var; |
1406 var = NonLocal(proxy->raw_name(), DYNAMIC_LOCAL, kind); | 1402 var = NonLocal(proxy->raw_name(), DYNAMIC_LOCAL); |
1407 var->set_local_if_not_shadowed(invalidated); | 1403 var->set_local_if_not_shadowed(invalidated); |
1408 } | 1404 } |
1409 break; | 1405 break; |
1410 | 1406 |
1411 case UNBOUND: | 1407 case UNBOUND: |
1412 // 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. |
1413 var = info->script_scope()->DeclareDynamicGlobal(proxy->raw_name(), kind); | 1409 var = info->script_scope()->DeclareDynamicGlobal(proxy->raw_name(), |
1410 Variable::NORMAL); | |
1414 break; | 1411 break; |
1415 | 1412 |
1416 case UNBOUND_EVAL_SHADOWED: | 1413 case UNBOUND_EVAL_SHADOWED: |
1417 // No binding has been found. But some scope makes a sloppy 'eval' call. | 1414 // No binding has been found. But some scope makes a sloppy 'eval' call. |
1418 var = NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL, kind); | 1415 var = NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL); |
1419 break; | 1416 break; |
1420 | 1417 |
1421 case DYNAMIC_LOOKUP: | 1418 case DYNAMIC_LOOKUP: |
1422 // The variable could not be resolved statically. | 1419 // The variable could not be resolved statically. |
1423 var = NonLocal(proxy->raw_name(), DYNAMIC, kind); | 1420 var = NonLocal(proxy->raw_name(), DYNAMIC); |
1424 break; | 1421 break; |
1425 } | 1422 } |
1426 | 1423 |
1427 DCHECK(var != NULL); | 1424 DCHECK(var != NULL); |
1428 if (proxy->is_assigned()) var->set_maybe_assigned(); | 1425 if (proxy->is_assigned()) var->set_maybe_assigned(); |
1429 | 1426 |
1430 proxy->BindTo(var); | 1427 proxy->BindTo(var); |
1431 } | 1428 } |
1432 | 1429 |
1433 void Scope::ResolveVariablesRecursively(ParseInfo* info, | 1430 void Scope::ResolveVariablesRecursively(ParseInfo* info, |
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1795 function != NULL && function->proxy()->var()->IsContextSlot(); | 1792 function != NULL && function->proxy()->var()->IsContextSlot(); |
1796 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - | 1793 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - |
1797 (is_function_var_in_context ? 1 : 0); | 1794 (is_function_var_in_context ? 1 : 0); |
1798 } | 1795 } |
1799 | 1796 |
1800 | 1797 |
1801 int Scope::ContextGlobalCount() const { return num_global_slots(); } | 1798 int Scope::ContextGlobalCount() const { return num_global_slots(); } |
1802 | 1799 |
1803 } // namespace internal | 1800 } // namespace internal |
1804 } // namespace v8 | 1801 } // namespace v8 |
OLD | NEW |