Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(251)

Side by Side Diff: src/interpreter/bytecode-generator.cc

Issue 1697473002: [interpreter] Add bytecodes for JumpIfNotHole with constant (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/interpreter/bytecode-generator.h ('k') | src/interpreter/bytecodes.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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/interpreter/bytecode-generator.h" 5 #include "src/interpreter/bytecode-generator.h"
6 6
7 #include "src/ast/scopes.h" 7 #include "src/ast/scopes.h"
8 #include "src/compiler.h" 8 #include "src/compiler.h"
9 #include "src/interpreter/bytecode-register-allocator.h" 9 #include "src/interpreter/bytecode-register-allocator.h"
10 #include "src/interpreter/control-flow-builders.h" 10 #include "src/interpreter/control-flow-builders.h"
(...skipping 1680 matching lines...) Expand 10 before | Expand all | Expand 10 after
1691 1691
1692 1692
1693 void BytecodeGenerator::VisitVariableProxy(VariableProxy* proxy) { 1693 void BytecodeGenerator::VisitVariableProxy(VariableProxy* proxy) {
1694 VisitVariableLoad(proxy->var(), proxy->VariableFeedbackSlot()); 1694 VisitVariableLoad(proxy->var(), proxy->VariableFeedbackSlot());
1695 } 1695 }
1696 1696
1697 void BytecodeGenerator::BuildHoleCheckForVariableLoad(VariableMode mode, 1697 void BytecodeGenerator::BuildHoleCheckForVariableLoad(VariableMode mode,
1698 Handle<String> name) { 1698 Handle<String> name) {
1699 if (mode == CONST_LEGACY) { 1699 if (mode == CONST_LEGACY) {
1700 BytecodeLabel end_label; 1700 BytecodeLabel end_label;
1701 builder()->JumpIfNotHole(&end_label); 1701 builder()->JumpIfNotHole(&end_label).LoadUndefined().Bind(&end_label);
1702 builder()->LoadUndefined();
1703 builder()->Bind(&end_label);
1704 } else if (mode == LET || mode == CONST) { 1702 } else if (mode == LET || mode == CONST) {
1705 BuildThrowIfHole(name); 1703 BuildThrowIfHole(name);
1706 } 1704 }
1707 } 1705 }
1708 1706
1709 void BytecodeGenerator::VisitVariableLoad(Variable* variable, 1707 void BytecodeGenerator::VisitVariableLoad(Variable* variable,
1710 FeedbackVectorSlot slot, 1708 FeedbackVectorSlot slot,
1711 TypeofMode typeof_mode) { 1709 TypeofMode typeof_mode) {
1712 VariableMode mode = variable->mode(); 1710 VariableMode mode = variable->mode();
1713 switch (variable->location()) { 1711 switch (variable->location()) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1763 break; 1761 break;
1764 } 1762 }
1765 case VariableLocation::LOOKUP: { 1763 case VariableLocation::LOOKUP: {
1766 builder()->LoadLookupSlot(variable->name(), typeof_mode); 1764 builder()->LoadLookupSlot(variable->name(), typeof_mode);
1767 execution_result()->SetResultInAccumulator(); 1765 execution_result()->SetResultInAccumulator();
1768 break; 1766 break;
1769 } 1767 }
1770 } 1768 }
1771 } 1769 }
1772 1770
1773
1774 void BytecodeGenerator::VisitVariableLoadForAccumulatorValue( 1771 void BytecodeGenerator::VisitVariableLoadForAccumulatorValue(
1775 Variable* variable, FeedbackVectorSlot slot, TypeofMode typeof_mode) { 1772 Variable* variable, FeedbackVectorSlot slot, TypeofMode typeof_mode) {
1776 AccumulatorResultScope accumulator_result(this); 1773 AccumulatorResultScope accumulator_result(this);
1777 VisitVariableLoad(variable, slot, typeof_mode); 1774 VisitVariableLoad(variable, slot, typeof_mode);
1778 } 1775 }
1779 1776
1780
1781 Register BytecodeGenerator::VisitVariableLoadForRegisterValue( 1777 Register BytecodeGenerator::VisitVariableLoadForRegisterValue(
1782 Variable* variable, FeedbackVectorSlot slot, TypeofMode typeof_mode) { 1778 Variable* variable, FeedbackVectorSlot slot, TypeofMode typeof_mode) {
1783 RegisterResultScope register_scope(this); 1779 RegisterResultScope register_scope(this);
1784 VisitVariableLoad(variable, slot, typeof_mode); 1780 VisitVariableLoad(variable, slot, typeof_mode);
1785 return register_scope.ResultRegister(); 1781 return register_scope.ResultRegister();
1786 } 1782 }
1787 1783
1784 void BytecodeGenerator::BuildThrowReferenceError(Handle<String> name) {
1785 RegisterAllocationScope register_scope(this);
1786 Register name_reg = register_allocator()->NewRegister();
1787 builder()->LoadLiteral(name).StoreAccumulatorInRegister(name_reg).CallRuntime(
1788 Runtime::kThrowReferenceError, name_reg, 1);
1789 }
1790
1788 void BytecodeGenerator::BuildThrowIfHole(Handle<String> name) { 1791 void BytecodeGenerator::BuildThrowIfHole(Handle<String> name) {
1789 Register name_reg = register_allocator()->NewRegister(); 1792 // TODO(interpreter): Can the parser reduce the number of checks
1790 BytecodeLabel end_label; 1793 // performed? Or should there be a ThrowIfHole bytecode.
1791 // TODO(mythria): This will be replaced by a new bytecode that throws an 1794 BytecodeLabel no_reference_error;
1792 // error if the value is the hole. 1795 builder()->JumpIfNotHole(&no_reference_error);
1793 builder() 1796 BuildThrowReferenceError(name);
1794 ->JumpIfNotHole(&end_label) 1797 builder()->Bind(&no_reference_error);
1795 .LoadLiteral(name)
1796 .StoreAccumulatorInRegister(name_reg)
1797 .CallRuntime(Runtime::kThrowReferenceError, name_reg, 1)
1798 .Bind(&end_label);
1799 } 1798 }
1800 1799
1801 void BytecodeGenerator::BuildThrowIfNotHole(Handle<String> name) { 1800 void BytecodeGenerator::BuildThrowIfNotHole(Handle<String> name) {
1802 Register name_reg = register_allocator()->NewRegister(); 1801 // TODO(interpreter): Can the parser reduce the number of checks
1803 BytecodeLabel end_label; 1802 // performed? Or should there be a ThrowIfNotHole bytecode.
1804 // TODO(mythria): This will be replaced by a new bytecode that throws an 1803 BytecodeLabel no_reference_error, reference_error;
1805 // error if the value is not the hole.
1806 builder() 1804 builder()
1807 ->JumpIfHole(&end_label) 1805 ->JumpIfNotHole(&reference_error)
1808 .LoadLiteral(name) 1806 .Jump(&no_reference_error)
1809 .StoreAccumulatorInRegister(name_reg) 1807 .Bind(&reference_error);
1810 .CallRuntime(Runtime::kThrowReferenceError, name_reg, 1) 1808 BuildThrowReferenceError(name);
1811 .Bind(&end_label); 1809 builder()->Bind(&no_reference_error);
1812 } 1810 }
1813 1811
1814 void BytecodeGenerator::BuildThrowReassignConstant(Handle<String> name) { 1812 void BytecodeGenerator::BuildThrowReassignConstant(Handle<String> name) {
1815 Register name_reg = register_allocator()->NewRegister();
1816 BytecodeLabel else_label;
1817 // TODO(mythria): This will be replaced by a new bytecode that throws an 1813 // TODO(mythria): This will be replaced by a new bytecode that throws an
1818 // appropriate error depending on the whether the value is a hole or not. 1814 // appropriate error depending on the whether the value is a hole or not.
1815 BytecodeLabel const_assign_error;
1816 builder()->JumpIfNotHole(&const_assign_error);
1817 BuildThrowReferenceError(name);
1819 builder() 1818 builder()
1820 ->JumpIfNotHole(&else_label) 1819 ->Bind(&const_assign_error)
1821 .LoadLiteral(name)
1822 .StoreAccumulatorInRegister(name_reg)
1823 .CallRuntime(Runtime::kThrowReferenceError, name_reg, 1)
1824 .Bind(&else_label)
1825 .CallRuntime(Runtime::kThrowConstAssignError, Register(), 0); 1820 .CallRuntime(Runtime::kThrowConstAssignError, Register(), 0);
1826 } 1821 }
1827 1822
1828 void BytecodeGenerator::BuildHoleCheckForVariableAssignment(Variable* variable, 1823 void BytecodeGenerator::BuildHoleCheckForVariableAssignment(Variable* variable,
1829 Token::Value op) { 1824 Token::Value op) {
1830 VariableMode mode = variable->mode(); 1825 VariableMode mode = variable->mode();
1831 DCHECK(mode != CONST_LEGACY); 1826 DCHECK(mode != CONST_LEGACY);
1832 if (mode == CONST && op != Token::INIT) { 1827 if (mode == CONST && op != Token::INIT) {
1833 // Non-intializing assignments to constant is not allowed. 1828 // Non-intializing assignments to constant is not allowed.
1834 BuildThrowReassignConstant(variable->name()); 1829 BuildThrowReassignConstant(variable->name());
1835 } else if (mode == LET && op != Token::INIT) { 1830 } else if (mode == LET && op != Token::INIT) {
1836 // Perform an initialization check for let declared variables. 1831 // Perform an initialization check for let declared variables.
1837 // E.g. let x = (x = 20); is not allowed. 1832 // E.g. let x = (x = 20); is not allowed.
1838 BuildThrowIfHole(variable->name()); 1833 BuildThrowIfHole(variable->name());
1839 } else { 1834 } else {
1840 DCHECK(variable->is_this() && mode == CONST && op == Token::INIT); 1835 DCHECK(variable->is_this() && mode == CONST && op == Token::INIT);
1841 // Perform an initialization check for 'this'. 'this' variable is the 1836 // Perform an initialization check for 'this'. 'this' variable is the
1842 // only variable able to trigger bind operations outside the TDZ 1837 // only variable able to trigger bind operations outside the TDZ
1843 // via 'super' calls. 1838 // via 'super' calls.
1844 BuildThrowIfNotHole(variable->name()); 1839 BuildThrowIfHole(variable->name());
1845 } 1840 }
1846 } 1841 }
1847 1842
1848 void BytecodeGenerator::VisitVariableAssignment(Variable* variable, 1843 void BytecodeGenerator::VisitVariableAssignment(Variable* variable,
1849 Token::Value op, 1844 Token::Value op,
1850 FeedbackVectorSlot slot) { 1845 FeedbackVectorSlot slot) {
1851 VariableMode mode = variable->mode(); 1846 VariableMode mode = variable->mode();
1852 RegisterAllocationScope assignment_register_scope(this); 1847 RegisterAllocationScope assignment_register_scope(this);
1853 BytecodeLabel end_label; 1848 BytecodeLabel end_label;
1854 bool hole_check_required = 1849 bool hole_check_required =
(...skipping 1036 matching lines...) Expand 10 before | Expand all | Expand 10 after
2891 } 2886 }
2892 2887
2893 2888
2894 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { 2889 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
2895 return info()->feedback_vector()->GetIndex(slot); 2890 return info()->feedback_vector()->GetIndex(slot);
2896 } 2891 }
2897 2892
2898 } // namespace interpreter 2893 } // namespace interpreter
2899 } // namespace internal 2894 } // namespace internal
2900 } // namespace v8 2895 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/bytecode-generator.h ('k') | src/interpreter/bytecodes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698