Chromium Code Reviews| 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 1286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1297 *binding_kind = UNBOUND; | 1297 *binding_kind = UNBOUND; |
| 1298 var = | 1298 var = |
| 1299 is_function_scope() | 1299 is_function_scope() |
| 1300 ? AsDeclarationScope()->LookupFunctionVar(proxy->raw_name(), factory) | 1300 ? AsDeclarationScope()->LookupFunctionVar(proxy->raw_name(), factory) |
| 1301 : nullptr; | 1301 : nullptr; |
| 1302 if (var != NULL) { | 1302 if (var != NULL) { |
| 1303 *binding_kind = BOUND; | 1303 *binding_kind = BOUND; |
| 1304 } else if (outer_scope_ != nullptr && this != max_outer_scope) { | 1304 } else if (outer_scope_ != nullptr && this != max_outer_scope) { |
| 1305 var = outer_scope_->LookupRecursive(proxy, binding_kind, factory, | 1305 var = outer_scope_->LookupRecursive(proxy, binding_kind, factory, |
| 1306 max_outer_scope); | 1306 max_outer_scope); |
| 1307 if (*binding_kind == BOUND && (is_function_scope() || is_with_scope())) { | 1307 if (*binding_kind == BOUND && is_function_scope()) { |
| 1308 var->ForceContextAllocation(); | 1308 var->ForceContextAllocation(); |
| 1309 } | 1309 } |
| 1310 } else { | 1310 } else { |
| 1311 DCHECK(is_script_scope() || this == max_outer_scope); | 1311 DCHECK(is_script_scope() || this == max_outer_scope); |
| 1312 } | 1312 } |
| 1313 | 1313 |
| 1314 // "this" can't be shadowed by "eval"-introduced bindings or by "with" scopes. | 1314 // "this" can't be shadowed by "eval"-introduced bindings or by "with" scopes. |
| 1315 // TODO(wingo): There are other variables in this category; add them. | 1315 // TODO(wingo): There are other variables in this category; add them. |
| 1316 bool name_can_be_shadowed = var == nullptr || !var->is_this(); | 1316 bool name_can_be_shadowed = var == nullptr || !var->is_this(); |
| 1317 | 1317 |
| 1318 if (is_with_scope() && name_can_be_shadowed) { | 1318 if (is_with_scope() && name_can_be_shadowed) { |
| 1319 DCHECK(!already_resolved()); | 1319 DCHECK(!already_resolved()); |
| 1320 // The current scope is a with scope, so the variable binding can not be | 1320 // The current scope is a with scope, so the variable binding can not be |
| 1321 // statically resolved. However, note that it was necessary to do a lookup | 1321 // statically resolved. However, note that it was necessary to do a lookup |
| 1322 // in the outer scope anyway, because if a binding exists in an outer scope, | 1322 // in the outer scope anyway, because if a binding exists in an outer scope, |
| 1323 // the associated variable has to be marked as potentially being accessed | 1323 // the associated variable has to be marked as potentially being accessed |
| 1324 // from inside of an inner with scope (the property may not be in the 'with' | 1324 // from inside of an inner with scope (the property may not be in the 'with' |
| 1325 // object). | 1325 // object). |
| 1326 if (var != NULL && proxy->is_assigned()) var->set_maybe_assigned(); | 1326 if (var != NULL) { |
| 1327 var->set_is_used(); | |
| 1328 var->ForceContextAllocation(); | |
| 1329 if (proxy->is_assigned()) var->set_maybe_assigned(); | |
| 1330 } | |
| 1327 *binding_kind = DYNAMIC_LOOKUP; | 1331 *binding_kind = DYNAMIC_LOOKUP; |
| 1328 return NULL; | 1332 return NULL; |
| 1329 } else if (calls_sloppy_eval() && is_declaration_scope() && | 1333 } else if (calls_sloppy_eval() && is_declaration_scope() && |
| 1330 !is_script_scope() && name_can_be_shadowed) { | 1334 !is_script_scope() && name_can_be_shadowed) { |
| 1331 // A variable binding may have been found in an outer scope, but the current | 1335 // A variable binding may have been found in an outer scope, but the current |
| 1332 // scope makes a sloppy 'eval' call, so the found variable may not be | 1336 // scope makes a sloppy 'eval' call, so the found variable may not be |
| 1333 // the correct one (the 'eval' may introduce a binding with the same name). | 1337 // the correct one (the 'eval' may introduce a binding with the same name). |
| 1334 // In that case, change the lookup result to reflect this situation. | 1338 // In that case, change the lookup result to reflect this situation. |
| 1335 // Only scopes that can host var bindings (declaration scopes) need be | 1339 // Only scopes that can host var bindings (declaration scopes) need be |
| 1336 // considered here (this excludes block and catch scopes), and variable | 1340 // considered here (this excludes block and catch scopes), and variable |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1482 } | 1486 } |
| 1483 } | 1487 } |
| 1484 | 1488 |
| 1485 | 1489 |
| 1486 bool Scope::MustAllocate(Variable* var) { | 1490 bool Scope::MustAllocate(Variable* var) { |
| 1487 DCHECK(var->location() != VariableLocation::MODULE); | 1491 DCHECK(var->location() != VariableLocation::MODULE); |
| 1488 // Give var a read/write use if there is a chance it might be accessed | 1492 // Give var a read/write use if there is a chance it might be accessed |
| 1489 // via an eval() call. This is only possible if the variable has a | 1493 // via an eval() call. This is only possible if the variable has a |
| 1490 // visible name. | 1494 // visible name. |
| 1491 if ((var->is_this() || !var->raw_name()->IsEmpty()) && | 1495 if ((var->is_this() || !var->raw_name()->IsEmpty()) && |
| 1492 (var->has_forced_context_allocation() || scope_calls_eval_ || | 1496 (scope_calls_eval_ || inner_scope_calls_eval_ || is_catch_scope() || |
| 1493 inner_scope_calls_eval_ || is_catch_scope() || is_block_scope() || | |
| 1494 is_script_scope())) { | 1497 is_script_scope())) { |
| 1495 var->set_is_used(); | 1498 var->set_is_used(); |
| 1496 if (scope_calls_eval_ || inner_scope_calls_eval_) var->set_maybe_assigned(); | 1499 if (scope_calls_eval_ || inner_scope_calls_eval_) var->set_maybe_assigned(); |
| 1497 } | 1500 } |
| 1498 // Global variables do not need to be allocated. | 1501 // Global variables do not need to be allocated. |
| 1499 return !var->IsGlobalObjectProperty() && var->is_used(); | 1502 return !var->IsGlobalObjectProperty() && var->is_used(); |
|
neis
2016/08/09 07:27:15
Can you add DCHECK(!var->has_forced_context_alloca
adamk
2016/08/09 16:25:18
Done.
| |
| 1500 } | 1503 } |
| 1501 | 1504 |
| 1502 | 1505 |
| 1503 bool Scope::MustAllocateInContext(Variable* var) { | 1506 bool Scope::MustAllocateInContext(Variable* var) { |
| 1504 // If var is accessed from an inner scope, or if there is a possibility | 1507 // If var is accessed from an inner scope, or if there is a possibility |
| 1505 // that it might be accessed from the current or an inner scope (through | 1508 // that it might be accessed from the current or an inner scope (through |
| 1506 // an eval() call or a runtime with lookup), it must be allocated in the | 1509 // an eval() call or a runtime with lookup), it must be allocated in the |
| 1507 // context. | 1510 // context. |
| 1508 // | 1511 // |
| 1509 // Exceptions: If the scope as a whole has forced context allocation, all | 1512 // Exceptions: If the scope as a whole has forced context allocation, all |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1782 function != NULL && function->proxy()->var()->IsContextSlot(); | 1785 function != NULL && function->proxy()->var()->IsContextSlot(); |
| 1783 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - | 1786 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - |
| 1784 (is_function_var_in_context ? 1 : 0); | 1787 (is_function_var_in_context ? 1 : 0); |
| 1785 } | 1788 } |
| 1786 | 1789 |
| 1787 | 1790 |
| 1788 int Scope::ContextGlobalCount() const { return num_global_slots(); } | 1791 int Scope::ContextGlobalCount() const { return num_global_slots(); } |
| 1789 | 1792 |
| 1790 } // namespace internal | 1793 } // namespace internal |
| 1791 } // namespace v8 | 1794 } // namespace v8 |
| OLD | NEW |