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