| 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/ast/ast.h" | 10 #include "src/ast/ast.h" |
| (...skipping 1379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1390 Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) { | 1390 Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) { |
| 1391 // Declare a new non-local. | 1391 // Declare a new non-local. |
| 1392 DCHECK(IsDynamicVariableMode(mode)); | 1392 DCHECK(IsDynamicVariableMode(mode)); |
| 1393 Variable* var = variables_.Declare(zone(), NULL, name, mode, NORMAL_VARIABLE, | 1393 Variable* var = variables_.Declare(zone(), NULL, name, mode, NORMAL_VARIABLE, |
| 1394 kCreatedInitialized); | 1394 kCreatedInitialized); |
| 1395 // Allocate it by giving it a dynamic lookup. | 1395 // Allocate it by giving it a dynamic lookup. |
| 1396 var->AllocateTo(VariableLocation::LOOKUP, -1); | 1396 var->AllocateTo(VariableLocation::LOOKUP, -1); |
| 1397 return var; | 1397 return var; |
| 1398 } | 1398 } |
| 1399 | 1399 |
| 1400 Variable* Scope::LookupRecursive(VariableProxy* proxy, bool declare_free, | 1400 Variable* Scope::LookupRecursive(VariableProxy* proxy, Scope* outer_scope_end) { |
| 1401 Scope* outer_scope_end) { | |
| 1402 DCHECK_NE(outer_scope_end, this); | 1401 DCHECK_NE(outer_scope_end, this); |
| 1403 // Short-cut: whenever we find a debug-evaluate scope, just look everything up | 1402 // Short-cut: whenever we find a debug-evaluate scope, just look everything up |
| 1404 // dynamically. Debug-evaluate doesn't properly create scope info for the | 1403 // dynamically. Debug-evaluate doesn't properly create scope info for the |
| 1405 // lookups it does. It may not have a valid 'this' declaration, and anything | 1404 // lookups it does. It may not have a valid 'this' declaration, and anything |
| 1406 // accessed through debug-evaluate might invalidly resolve to stack-allocated | 1405 // accessed through debug-evaluate might invalidly resolve to stack-allocated |
| 1407 // variables. | 1406 // variables. |
| 1408 // TODO(yangguo): Remove once debug-evaluate creates proper ScopeInfo for the | 1407 // TODO(yangguo): Remove once debug-evaluate creates proper ScopeInfo for the |
| 1409 // scopes in which it's evaluating. | 1408 // scopes in which it's evaluating. |
| 1410 if (is_debug_evaluate_scope_) { | 1409 if (is_debug_evaluate_scope_) return NonLocal(proxy->raw_name(), DYNAMIC); |
| 1411 if (!declare_free) return nullptr; | |
| 1412 return NonLocal(proxy->raw_name(), DYNAMIC); | |
| 1413 } | |
| 1414 | 1410 |
| 1415 // Try to find the variable in this scope. | 1411 // Try to find the variable in this scope. |
| 1416 Variable* var = LookupLocal(proxy->raw_name()); | 1412 Variable* var = LookupLocal(proxy->raw_name()); |
| 1417 | 1413 |
| 1418 // We found a variable and we are done. (Even if there is an 'eval' in this | 1414 // We found a variable and we are done. (Even if there is an 'eval' in this |
| 1419 // scope which introduces the same variable again, the resulting variable | 1415 // scope which introduces the same variable again, the resulting variable |
| 1420 // remains the same.) | 1416 // remains the same.) |
| 1421 if (var != nullptr) return var; | 1417 if (var != nullptr) return var; |
| 1422 | 1418 |
| 1423 // We did not find a variable locally. Check against the function variable, if | 1419 // We did not find a variable locally. Check against the function variable, if |
| 1424 // any. | 1420 // any. |
| 1425 if (is_function_scope()) { | 1421 if (is_function_scope()) { |
| 1426 var = AsDeclarationScope()->LookupFunctionVar(proxy->raw_name()); | 1422 var = AsDeclarationScope()->LookupFunctionVar(proxy->raw_name()); |
| 1427 if (var != nullptr) { | 1423 if (var != nullptr) { |
| 1428 if (calls_sloppy_eval()) return NonLocal(proxy->raw_name(), DYNAMIC); | 1424 if (calls_sloppy_eval()) return NonLocal(proxy->raw_name(), DYNAMIC); |
| 1429 return var; | 1425 return var; |
| 1430 } | 1426 } |
| 1431 } | 1427 } |
| 1432 | 1428 |
| 1433 if (outer_scope_ == outer_scope_end) { | 1429 if (outer_scope_ == outer_scope_end) { |
| 1434 if (!declare_free) return nullptr; | 1430 // We may just be trying to find all free variables. In that case, don't |
| 1435 DCHECK(is_script_scope()); | 1431 // declare them in the outer scope. |
| 1432 if (!is_script_scope()) return nullptr; |
| 1436 // No binding has been found. Declare a variable on the global object. | 1433 // No binding has been found. Declare a variable on the global object. |
| 1437 return AsDeclarationScope()->DeclareDynamicGlobal(proxy->raw_name(), | 1434 return AsDeclarationScope()->DeclareDynamicGlobal(proxy->raw_name(), |
| 1438 NORMAL_VARIABLE); | 1435 NORMAL_VARIABLE); |
| 1439 } | 1436 } |
| 1440 | 1437 |
| 1441 DCHECK(!is_script_scope()); | 1438 DCHECK(!is_script_scope()); |
| 1442 | 1439 |
| 1443 var = outer_scope_->LookupRecursive(proxy, declare_free, outer_scope_end); | 1440 var = outer_scope_->LookupRecursive(proxy, outer_scope_end); |
| 1444 | 1441 |
| 1445 // The variable could not be resolved statically. | 1442 // The variable could not be resolved statically. |
| 1446 if (var == nullptr) return var; | 1443 if (var == nullptr) return var; |
| 1447 | 1444 |
| 1448 if (is_function_scope() && !var->is_dynamic()) { | 1445 if (is_function_scope() && !var->is_dynamic()) { |
| 1449 var->ForceContextAllocation(); | 1446 var->ForceContextAllocation(); |
| 1450 } | 1447 } |
| 1451 // "this" can't be shadowed by "eval"-introduced bindings or by "with" | 1448 // "this" can't be shadowed by "eval"-introduced bindings or by "with" |
| 1452 // scopes. | 1449 // scopes. |
| 1453 // TODO(wingo): There are other variables in this category; add them. | 1450 // TODO(wingo): There are other variables in this category; add them. |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1492 } | 1489 } |
| 1493 | 1490 |
| 1494 void Scope::ResolveVariable(ParseInfo* info, VariableProxy* proxy) { | 1491 void Scope::ResolveVariable(ParseInfo* info, VariableProxy* proxy) { |
| 1495 DCHECK(info->script_scope()->is_script_scope()); | 1492 DCHECK(info->script_scope()->is_script_scope()); |
| 1496 | 1493 |
| 1497 // If the proxy is already resolved there's nothing to do | 1494 // If the proxy is already resolved there's nothing to do |
| 1498 // (functions and consts may be resolved by the parser). | 1495 // (functions and consts may be resolved by the parser). |
| 1499 if (proxy->is_resolved()) return; | 1496 if (proxy->is_resolved()) return; |
| 1500 | 1497 |
| 1501 // Otherwise, try to resolve the variable. | 1498 // Otherwise, try to resolve the variable. |
| 1502 Variable* var = LookupRecursive(proxy, true, nullptr); | 1499 Variable* var = LookupRecursive(proxy, nullptr); |
| 1503 | 1500 |
| 1504 ResolveTo(info, proxy, var); | 1501 ResolveTo(info, proxy, var); |
| 1505 } | 1502 } |
| 1506 | 1503 |
| 1507 void Scope::ResolveTo(ParseInfo* info, VariableProxy* proxy, Variable* var) { | 1504 void Scope::ResolveTo(ParseInfo* info, VariableProxy* proxy, Variable* var) { |
| 1508 #ifdef DEBUG | 1505 #ifdef DEBUG |
| 1509 if (info->script_is_native()) { | 1506 if (info->script_is_native()) { |
| 1510 // To avoid polluting the global object in native scripts | 1507 // To avoid polluting the global object in native scripts |
| 1511 // - Variables must not be allocated to the global scope. | 1508 // - Variables must not be allocated to the global scope. |
| 1512 CHECK_NOT_NULL(outer_scope()); | 1509 CHECK_NOT_NULL(outer_scope()); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1546 } | 1543 } |
| 1547 } | 1544 } |
| 1548 | 1545 |
| 1549 VariableProxy* Scope::FetchFreeVariables(DeclarationScope* max_outer_scope, | 1546 VariableProxy* Scope::FetchFreeVariables(DeclarationScope* max_outer_scope, |
| 1550 ParseInfo* info, | 1547 ParseInfo* info, |
| 1551 VariableProxy* stack) { | 1548 VariableProxy* stack) { |
| 1552 for (VariableProxy *proxy = unresolved_, *next = nullptr; proxy != nullptr; | 1549 for (VariableProxy *proxy = unresolved_, *next = nullptr; proxy != nullptr; |
| 1553 proxy = next) { | 1550 proxy = next) { |
| 1554 next = proxy->next_unresolved(); | 1551 next = proxy->next_unresolved(); |
| 1555 if (proxy->is_resolved()) continue; | 1552 if (proxy->is_resolved()) continue; |
| 1556 Variable* var = | 1553 Variable* var = LookupRecursive(proxy, max_outer_scope->outer_scope()); |
| 1557 LookupRecursive(proxy, false, max_outer_scope->outer_scope()); | |
| 1558 if (var == nullptr) { | 1554 if (var == nullptr) { |
| 1559 proxy->set_next_unresolved(stack); | 1555 proxy->set_next_unresolved(stack); |
| 1560 stack = proxy; | 1556 stack = proxy; |
| 1561 } else if (info != nullptr) { | 1557 } else if (info != nullptr) { |
| 1562 ResolveTo(info, proxy, var); | 1558 ResolveTo(info, proxy, var); |
| 1563 } | 1559 } |
| 1564 } | 1560 } |
| 1565 | 1561 |
| 1566 // Clear unresolved_ as it's in an inconsistent state. | 1562 // Clear unresolved_ as it's in an inconsistent state. |
| 1567 unresolved_ = nullptr; | 1563 unresolved_ = nullptr; |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1816 Variable* function = | 1812 Variable* function = |
| 1817 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; | 1813 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; |
| 1818 bool is_function_var_in_context = | 1814 bool is_function_var_in_context = |
| 1819 function != nullptr && function->IsContextSlot(); | 1815 function != nullptr && function->IsContextSlot(); |
| 1820 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 1816 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
| 1821 (is_function_var_in_context ? 1 : 0); | 1817 (is_function_var_in_context ? 1 : 0); |
| 1822 } | 1818 } |
| 1823 | 1819 |
| 1824 } // namespace internal | 1820 } // namespace internal |
| 1825 } // namespace v8 | 1821 } // namespace v8 |
| OLD | NEW |