| OLD | NEW |
| 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/code-stubs.h" | 8 #include "src/code-stubs.h" |
| 9 #include "src/compiler.h" | 9 #include "src/compiler.h" |
| 10 #include "src/interpreter/bytecode-flags.h" | 10 #include "src/interpreter/bytecode-flags.h" |
| (...skipping 814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 825 ControlScopeForBreakable execution_control(this, stmt, &block_builder); | 825 ControlScopeForBreakable execution_control(this, stmt, &block_builder); |
| 826 if (stmt->scope() != nullptr) { | 826 if (stmt->scope() != nullptr) { |
| 827 VisitDeclarations(stmt->scope()->declarations()); | 827 VisitDeclarations(stmt->scope()->declarations()); |
| 828 } | 828 } |
| 829 VisitStatements(stmt->statements()); | 829 VisitStatements(stmt->statements()); |
| 830 if (stmt->labels() != nullptr) block_builder.EndBlock(); | 830 if (stmt->labels() != nullptr) block_builder.EndBlock(); |
| 831 } | 831 } |
| 832 | 832 |
| 833 void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) { | 833 void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) { |
| 834 Variable* variable = decl->proxy()->var(); | 834 Variable* variable = decl->proxy()->var(); |
| 835 VariableMode mode = decl->mode(); | |
| 836 // Const and let variables are initialized with the hole so that we can | |
| 837 // check that they are only assigned once. | |
| 838 bool hole_init = mode == CONST || mode == LET; | |
| 839 switch (variable->location()) { | 835 switch (variable->location()) { |
| 840 case VariableLocation::GLOBAL: | 836 case VariableLocation::GLOBAL: |
| 841 case VariableLocation::UNALLOCATED: { | 837 case VariableLocation::UNALLOCATED: { |
| 842 DCHECK(!variable->binding_needs_init()); | 838 DCHECK(!variable->binding_needs_init()); |
| 843 FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot(); | 839 FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot(); |
| 844 globals_builder()->AddUndefinedDeclaration(slot); | 840 globals_builder()->AddUndefinedDeclaration(slot); |
| 845 break; | 841 break; |
| 846 } | 842 } |
| 847 case VariableLocation::LOCAL: | 843 case VariableLocation::LOCAL: |
| 848 if (hole_init) { | 844 if (variable->binding_needs_init()) { |
| 849 Register destination(variable->index()); | 845 Register destination(variable->index()); |
| 850 builder()->LoadTheHole().StoreAccumulatorInRegister(destination); | 846 builder()->LoadTheHole().StoreAccumulatorInRegister(destination); |
| 851 } | 847 } |
| 852 break; | 848 break; |
| 853 case VariableLocation::PARAMETER: | 849 case VariableLocation::PARAMETER: |
| 854 if (hole_init) { | 850 if (variable->binding_needs_init()) { |
| 855 // The parameter indices are shifted by 1 (receiver is variable | 851 // The parameter indices are shifted by 1 (receiver is variable |
| 856 // index -1 but is parameter index 0 in BytecodeArrayBuilder). | 852 // index -1 but is parameter index 0 in BytecodeArrayBuilder). |
| 857 Register destination(builder()->Parameter(variable->index() + 1)); | 853 Register destination(builder()->Parameter(variable->index() + 1)); |
| 858 builder()->LoadTheHole().StoreAccumulatorInRegister(destination); | 854 builder()->LoadTheHole().StoreAccumulatorInRegister(destination); |
| 859 } | 855 } |
| 860 break; | 856 break; |
| 861 case VariableLocation::CONTEXT: | 857 case VariableLocation::CONTEXT: |
| 862 if (hole_init) { | 858 if (variable->binding_needs_init()) { |
| 863 builder()->LoadTheHole().StoreContextSlot(execution_context()->reg(), | 859 builder()->LoadTheHole().StoreContextSlot(execution_context()->reg(), |
| 864 variable->index()); | 860 variable->index()); |
| 865 } | 861 } |
| 866 break; | 862 break; |
| 867 case VariableLocation::LOOKUP: { | 863 case VariableLocation::LOOKUP: { |
| 868 DCHECK_EQ(VAR, mode); | 864 DCHECK_EQ(VAR, variable->mode()); |
| 869 DCHECK(!hole_init); | 865 DCHECK(!variable->binding_needs_init()); |
| 870 | 866 |
| 871 Register name = register_allocator()->NewRegister(); | 867 Register name = register_allocator()->NewRegister(); |
| 872 | 868 |
| 873 builder() | 869 builder() |
| 874 ->LoadLiteral(variable->name()) | 870 ->LoadLiteral(variable->name()) |
| 875 .StoreAccumulatorInRegister(name) | 871 .StoreAccumulatorInRegister(name) |
| 876 .CallRuntime(Runtime::kDeclareEvalVar, name, 1); | 872 .CallRuntime(Runtime::kDeclareEvalVar, name, 1); |
| 877 break; | 873 break; |
| 878 } | 874 } |
| 879 } | 875 } |
| (...skipping 956 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1836 builder()->LoadAccumulatorWithRegister(literal); | 1832 builder()->LoadAccumulatorWithRegister(literal); |
| 1837 } | 1833 } |
| 1838 execution_result()->SetResultInAccumulator(); | 1834 execution_result()->SetResultInAccumulator(); |
| 1839 } | 1835 } |
| 1840 | 1836 |
| 1841 void BytecodeGenerator::VisitVariableProxy(VariableProxy* proxy) { | 1837 void BytecodeGenerator::VisitVariableProxy(VariableProxy* proxy) { |
| 1842 builder()->SetExpressionPosition(proxy); | 1838 builder()->SetExpressionPosition(proxy); |
| 1843 VisitVariableLoad(proxy->var(), proxy->VariableFeedbackSlot()); | 1839 VisitVariableLoad(proxy->var(), proxy->VariableFeedbackSlot()); |
| 1844 } | 1840 } |
| 1845 | 1841 |
| 1846 void BytecodeGenerator::BuildHoleCheckForVariableLoad(VariableMode mode, | 1842 void BytecodeGenerator::BuildHoleCheckForVariableLoad(Variable* variable) { |
| 1847 Handle<String> name) { | 1843 if (variable->binding_needs_init()) { |
| 1848 if (mode == LET || mode == CONST) { | 1844 BuildThrowIfHole(variable->name()); |
| 1849 BuildThrowIfHole(name); | |
| 1850 } | 1845 } |
| 1851 } | 1846 } |
| 1852 | 1847 |
| 1853 void BytecodeGenerator::VisitVariableLoad(Variable* variable, | 1848 void BytecodeGenerator::VisitVariableLoad(Variable* variable, |
| 1854 FeedbackVectorSlot slot, | 1849 FeedbackVectorSlot slot, |
| 1855 TypeofMode typeof_mode) { | 1850 TypeofMode typeof_mode) { |
| 1856 VariableMode mode = variable->mode(); | |
| 1857 switch (variable->location()) { | 1851 switch (variable->location()) { |
| 1858 case VariableLocation::LOCAL: { | 1852 case VariableLocation::LOCAL: { |
| 1859 Register source(Register(variable->index())); | 1853 Register source(Register(variable->index())); |
| 1860 builder()->LoadAccumulatorWithRegister(source); | 1854 builder()->LoadAccumulatorWithRegister(source); |
| 1861 BuildHoleCheckForVariableLoad(mode, variable->name()); | 1855 BuildHoleCheckForVariableLoad(variable); |
| 1862 execution_result()->SetResultInAccumulator(); | 1856 execution_result()->SetResultInAccumulator(); |
| 1863 break; | 1857 break; |
| 1864 } | 1858 } |
| 1865 case VariableLocation::PARAMETER: { | 1859 case VariableLocation::PARAMETER: { |
| 1866 // The parameter indices are shifted by 1 (receiver is variable | 1860 // The parameter indices are shifted by 1 (receiver is variable |
| 1867 // index -1 but is parameter index 0 in BytecodeArrayBuilder). | 1861 // index -1 but is parameter index 0 in BytecodeArrayBuilder). |
| 1868 Register source = builder()->Parameter(variable->index() + 1); | 1862 Register source = builder()->Parameter(variable->index() + 1); |
| 1869 builder()->LoadAccumulatorWithRegister(source); | 1863 builder()->LoadAccumulatorWithRegister(source); |
| 1870 BuildHoleCheckForVariableLoad(mode, variable->name()); | 1864 BuildHoleCheckForVariableLoad(variable); |
| 1871 execution_result()->SetResultInAccumulator(); | 1865 execution_result()->SetResultInAccumulator(); |
| 1872 break; | 1866 break; |
| 1873 } | 1867 } |
| 1874 case VariableLocation::GLOBAL: | 1868 case VariableLocation::GLOBAL: |
| 1875 case VariableLocation::UNALLOCATED: { | 1869 case VariableLocation::UNALLOCATED: { |
| 1876 builder()->LoadGlobal(feedback_index(slot), typeof_mode); | 1870 builder()->LoadGlobal(feedback_index(slot), typeof_mode); |
| 1877 execution_result()->SetResultInAccumulator(); | 1871 execution_result()->SetResultInAccumulator(); |
| 1878 break; | 1872 break; |
| 1879 } | 1873 } |
| 1880 case VariableLocation::CONTEXT: { | 1874 case VariableLocation::CONTEXT: { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1894 ->LoadAccumulatorWithRegister(execution_context()->reg()) | 1888 ->LoadAccumulatorWithRegister(execution_context()->reg()) |
| 1895 .StoreAccumulatorInRegister(context_reg); | 1889 .StoreAccumulatorInRegister(context_reg); |
| 1896 for (int i = 0; i < depth; ++i) { | 1890 for (int i = 0; i < depth; ++i) { |
| 1897 builder() | 1891 builder() |
| 1898 ->LoadContextSlot(context_reg, Context::PREVIOUS_INDEX) | 1892 ->LoadContextSlot(context_reg, Context::PREVIOUS_INDEX) |
| 1899 .StoreAccumulatorInRegister(context_reg); | 1893 .StoreAccumulatorInRegister(context_reg); |
| 1900 } | 1894 } |
| 1901 } | 1895 } |
| 1902 | 1896 |
| 1903 builder()->LoadContextSlot(context_reg, variable->index()); | 1897 builder()->LoadContextSlot(context_reg, variable->index()); |
| 1904 BuildHoleCheckForVariableLoad(mode, variable->name()); | 1898 BuildHoleCheckForVariableLoad(variable); |
| 1905 execution_result()->SetResultInAccumulator(); | 1899 execution_result()->SetResultInAccumulator(); |
| 1906 break; | 1900 break; |
| 1907 } | 1901 } |
| 1908 case VariableLocation::LOOKUP: { | 1902 case VariableLocation::LOOKUP: { |
| 1909 builder()->LoadLookupSlot(variable->name(), typeof_mode); | 1903 builder()->LoadLookupSlot(variable->name(), typeof_mode); |
| 1910 execution_result()->SetResultInAccumulator(); | 1904 execution_result()->SetResultInAccumulator(); |
| 1911 break; | 1905 break; |
| 1912 } | 1906 } |
| 1913 } | 1907 } |
| 1914 } | 1908 } |
| (...skipping 1356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3271 return execution_context()->scope()->language_mode(); | 3265 return execution_context()->scope()->language_mode(); |
| 3272 } | 3266 } |
| 3273 | 3267 |
| 3274 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 3268 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
| 3275 return TypeFeedbackVector::GetIndex(slot); | 3269 return TypeFeedbackVector::GetIndex(slot); |
| 3276 } | 3270 } |
| 3277 | 3271 |
| 3278 } // namespace interpreter | 3272 } // namespace interpreter |
| 3279 } // namespace internal | 3273 } // namespace internal |
| 3280 } // namespace v8 | 3274 } // namespace v8 |
| OLD | NEW |