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.h" | 5 #include "src/ast.h" |
6 #include "src/ast-numbering.h" | 6 #include "src/ast-numbering.h" |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/compiler.h" | 9 #include "src/compiler.h" |
10 #include "src/debug/debug.h" | 10 #include "src/debug/debug.h" |
(...skipping 1572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1583 Context::PREVIOUS_INDEX); | 1583 Context::PREVIOUS_INDEX); |
1584 // Update local stack frame context field. | 1584 // Update local stack frame context field. |
1585 codegen_->StoreToFrameField(StandardFrameConstants::kContextOffset, | 1585 codegen_->StoreToFrameField(StandardFrameConstants::kContextOffset, |
1586 codegen_->context_register()); | 1586 codegen_->context_register()); |
1587 } | 1587 } |
1588 codegen_->PrepareForBailoutForId(exit_id_, NO_REGISTERS); | 1588 codegen_->PrepareForBailoutForId(exit_id_, NO_REGISTERS); |
1589 codegen_->scope_ = saved_scope_; | 1589 codegen_->scope_ = saved_scope_; |
1590 } | 1590 } |
1591 | 1591 |
1592 | 1592 |
| 1593 bool FullCodeGenerator::NeedsHoleCheckForLoad(VariableProxy* proxy) { |
| 1594 Variable* var = proxy->var(); |
| 1595 |
| 1596 if (!var->binding_needs_init()) { |
| 1597 return false; |
| 1598 } |
| 1599 |
| 1600 // var->scope() may be NULL when the proxy is located in eval code and |
| 1601 // refers to a potential outside binding. Currently those bindings are |
| 1602 // always looked up dynamically, i.e. in that case |
| 1603 // var->location() == LOOKUP. |
| 1604 // always holds. |
| 1605 DCHECK(var->scope() != NULL); |
| 1606 DCHECK(var->location() == VariableLocation::PARAMETER || |
| 1607 var->location() == VariableLocation::LOCAL || |
| 1608 var->location() == VariableLocation::CONTEXT); |
| 1609 |
| 1610 // Check if the binding really needs an initialization check. The check |
| 1611 // can be skipped in the following situation: we have a LET or CONST |
| 1612 // binding in harmony mode, both the Variable and the VariableProxy have |
| 1613 // the same declaration scope (i.e. they are both in global code, in the |
| 1614 // same function or in the same eval code), the VariableProxy is in |
| 1615 // the source physically located after the initializer of the variable, |
| 1616 // and that the initializer cannot be skipped due to a nonlinear scope. |
| 1617 // |
| 1618 // We cannot skip any initialization checks for CONST in non-harmony |
| 1619 // mode because const variables may be declared but never initialized: |
| 1620 // if (false) { const x; }; var y = x; |
| 1621 // |
| 1622 // The condition on the declaration scopes is a conservative check for |
| 1623 // nested functions that access a binding and are called before the |
| 1624 // binding is initialized: |
| 1625 // function() { f(); let x = 1; function f() { x = 2; } } |
| 1626 // |
| 1627 // The check cannot be skipped on non-linear scopes, namely switch |
| 1628 // scopes, to ensure tests are done in cases like the following: |
| 1629 // switch (1) { case 0: let x = 2; case 1: f(x); } |
| 1630 // The scope of the variable needs to be checked, in case the use is |
| 1631 // in a sub-block which may be linear. |
| 1632 if (var->scope()->DeclarationScope() != scope()->DeclarationScope()) { |
| 1633 return true; |
| 1634 } |
| 1635 |
| 1636 if (var->is_this()) { |
| 1637 DCHECK(literal() != nullptr && |
| 1638 (literal()->kind() & kSubclassConstructor) != 0); |
| 1639 // TODO(littledan): implement 'this' hole check elimination. |
| 1640 return true; |
| 1641 } |
| 1642 |
| 1643 // Check that we always have valid source position. |
| 1644 DCHECK(var->initializer_position() != RelocInfo::kNoPosition); |
| 1645 DCHECK(proxy->position() != RelocInfo::kNoPosition); |
| 1646 |
| 1647 return var->mode() == CONST_LEGACY || var->scope()->is_nonlinear() || |
| 1648 var->initializer_position() >= proxy->position(); |
| 1649 } |
| 1650 |
| 1651 |
1593 #undef __ | 1652 #undef __ |
1594 | 1653 |
1595 | 1654 |
1596 } // namespace internal | 1655 } // namespace internal |
1597 } // namespace v8 | 1656 } // namespace v8 |
OLD | NEW |