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.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 |