| 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/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 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 } | 410 } |
| 411 | 411 |
| 412 void PrepareForConsecutiveAllocations(int count) { | 412 void PrepareForConsecutiveAllocations(int count) { |
| 413 allocator_.PrepareForConsecutiveAllocations(count); | 413 allocator_.PrepareForConsecutiveAllocations(count); |
| 414 } | 414 } |
| 415 | 415 |
| 416 Register NextConsecutiveRegister() { | 416 Register NextConsecutiveRegister() { |
| 417 return allocator_.NextConsecutiveRegister(); | 417 return allocator_.NextConsecutiveRegister(); |
| 418 } | 418 } |
| 419 | 419 |
| 420 template <size_t N> | |
| 421 void PrepareAndInitializeConsecutiveAllocations(Register (®isters)[N]) { | |
| 422 return allocator_.PrepareAndInitializeConsecutiveAllocations(registers, N); | |
| 423 } | |
| 424 | |
| 425 bool RegisterIsAllocatedInThisScope(Register reg) const { | 420 bool RegisterIsAllocatedInThisScope(Register reg) const { |
| 426 return allocator_.RegisterIsAllocatedInThisScope(reg); | 421 return allocator_.RegisterIsAllocatedInThisScope(reg); |
| 427 } | 422 } |
| 428 | 423 |
| 429 RegisterAllocationScope* outer() const { return outer_; } | 424 RegisterAllocationScope* outer() const { return outer_; } |
| 430 | 425 |
| 431 private: | 426 private: |
| 432 BytecodeGenerator* generator() const { return generator_; } | 427 BytecodeGenerator* generator() const { return generator_; } |
| 433 BytecodeArrayBuilder* builder() const { return generator_->builder(); } | 428 BytecodeArrayBuilder* builder() const { return generator_->builder(); } |
| 434 | 429 |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 540 result_register_ = reg; | 535 result_register_ = reg; |
| 541 set_result_identified(); | 536 set_result_identified(); |
| 542 } | 537 } |
| 543 | 538 |
| 544 Register ResultRegister() const { return result_register_; } | 539 Register ResultRegister() const { return result_register_; } |
| 545 | 540 |
| 546 private: | 541 private: |
| 547 Register result_register_; | 542 Register result_register_; |
| 548 }; | 543 }; |
| 549 | 544 |
| 550 // Class for holding arguments for runtime calls relating to super | |
| 551 // properties. | |
| 552 class BytecodeGenerator::SuperPropertyArguments final { | |
| 553 public: | |
| 554 SuperPropertyArguments() {} | |
| 555 | |
| 556 Register (®isters())[4] { return args_; } | |
| 557 Register receiver() const { return args_[0]; } | |
| 558 Register home_object() const { return args_[1]; } | |
| 559 Register name_or_key() const { return args_[2]; } | |
| 560 Register store_value() const { return args_[3]; } | |
| 561 Register language_mode() const { return args_[3]; } | |
| 562 size_t count() const { return arraysize(args_); } | |
| 563 | |
| 564 private: | |
| 565 Register args_[4]; | |
| 566 | |
| 567 DISALLOW_COPY_AND_ASSIGN(SuperPropertyArguments); | |
| 568 }; | |
| 569 | |
| 570 BytecodeGenerator::BytecodeGenerator(Isolate* isolate, Zone* zone) | 545 BytecodeGenerator::BytecodeGenerator(Isolate* isolate, Zone* zone) |
| 571 : isolate_(isolate), | 546 : isolate_(isolate), |
| 572 zone_(zone), | 547 zone_(zone), |
| 573 builder_(nullptr), | 548 builder_(nullptr), |
| 574 info_(nullptr), | 549 info_(nullptr), |
| 575 scope_(nullptr), | 550 scope_(nullptr), |
| 576 globals_(0, zone), | 551 globals_(0, zone), |
| 577 execution_control_(nullptr), | 552 execution_control_(nullptr), |
| 578 execution_context_(nullptr), | 553 execution_context_(nullptr), |
| 579 execution_result_(nullptr), | 554 execution_result_(nullptr), |
| (...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1067 builder()->StoreAccumulatorInRegister(value); | 1042 builder()->StoreAccumulatorInRegister(value); |
| 1068 Register object = VisitForRegisterValue(property->obj()); | 1043 Register object = VisitForRegisterValue(property->obj()); |
| 1069 Register key = VisitForRegisterValue(property->key()); | 1044 Register key = VisitForRegisterValue(property->key()); |
| 1070 builder()->LoadAccumulatorWithRegister(value); | 1045 builder()->LoadAccumulatorWithRegister(value); |
| 1071 builder()->StoreKeyedProperty(object, key, feedback_index(slot), | 1046 builder()->StoreKeyedProperty(object, key, feedback_index(slot), |
| 1072 language_mode()); | 1047 language_mode()); |
| 1073 break; | 1048 break; |
| 1074 } | 1049 } |
| 1075 case NAMED_SUPER_PROPERTY: { | 1050 case NAMED_SUPER_PROPERTY: { |
| 1076 RegisterAllocationScope register_scope(this); | 1051 RegisterAllocationScope register_scope(this); |
| 1077 SuperPropertyArguments super_args; | 1052 register_allocator()->PrepareForConsecutiveAllocations(4); |
| 1078 Register value = register_allocator()->NewRegister(); | 1053 Register receiver = register_allocator()->NextConsecutiveRegister(); |
| 1054 Register home_object = register_allocator()->NextConsecutiveRegister(); |
| 1055 Register name = register_allocator()->NextConsecutiveRegister(); |
| 1056 Register value = register_allocator()->NextConsecutiveRegister(); |
| 1079 builder()->StoreAccumulatorInRegister(value); | 1057 builder()->StoreAccumulatorInRegister(value); |
| 1080 PrepareNamedSuperPropertyArguments( | 1058 SuperPropertyReference* super_property = |
| 1081 property->obj()->AsSuperPropertyReference(), | 1059 property->obj()->AsSuperPropertyReference(); |
| 1082 property->key()->AsLiteral()->AsPropertyName(), &super_args); | 1060 VisitForRegisterValue(super_property->this_var(), receiver); |
| 1083 builder()->LoadAccumulatorWithRegister(value); | 1061 VisitForRegisterValue(super_property->home_object(), home_object); |
| 1084 BuildNamedSuperPropertyStore(&super_args); | 1062 builder() |
| 1063 ->LoadLiteral(property->key()->AsLiteral()->AsPropertyName()) |
| 1064 .StoreAccumulatorInRegister(name); |
| 1065 BuildNamedSuperPropertyStore(receiver, home_object, name, value); |
| 1085 break; | 1066 break; |
| 1086 } | 1067 } |
| 1087 case KEYED_SUPER_PROPERTY: { | 1068 case KEYED_SUPER_PROPERTY: { |
| 1088 RegisterAllocationScope register_scope(this); | 1069 RegisterAllocationScope register_scope(this); |
| 1089 SuperPropertyArguments super_args; | 1070 register_allocator()->PrepareForConsecutiveAllocations(4); |
| 1090 Register value = register_allocator()->NewRegister(); | 1071 Register receiver = register_allocator()->NextConsecutiveRegister(); |
| 1072 Register home_object = register_allocator()->NextConsecutiveRegister(); |
| 1073 Register key = register_allocator()->NextConsecutiveRegister(); |
| 1074 Register value = register_allocator()->NextConsecutiveRegister(); |
| 1091 builder()->StoreAccumulatorInRegister(value); | 1075 builder()->StoreAccumulatorInRegister(value); |
| 1092 PrepareKeyedSuperPropertyArguments( | 1076 SuperPropertyReference* super_property = |
| 1093 property->obj()->AsSuperPropertyReference(), property->key(), | 1077 property->obj()->AsSuperPropertyReference(); |
| 1094 &super_args); | 1078 VisitForRegisterValue(super_property->this_var(), receiver); |
| 1095 builder()->LoadAccumulatorWithRegister(value); | 1079 VisitForRegisterValue(super_property->home_object(), home_object); |
| 1096 BuildKeyedSuperPropertyStore(&super_args); | 1080 VisitForRegisterValue(property->key(), key); |
| 1081 BuildKeyedSuperPropertyStore(receiver, home_object, key, value); |
| 1097 break; | 1082 break; |
| 1098 } | 1083 } |
| 1099 } | 1084 } |
| 1100 } | 1085 } |
| 1101 | 1086 |
| 1102 | 1087 |
| 1103 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) { | 1088 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) { |
| 1104 if (stmt->subject()->IsNullLiteral() || | 1089 if (stmt->subject()->IsNullLiteral() || |
| 1105 stmt->subject()->IsUndefinedLiteral(isolate())) { | 1090 stmt->subject()->IsUndefinedLiteral(isolate())) { |
| 1106 // ForIn generates lots of code, skip if it wouldn't produce any effects. | 1091 // ForIn generates lots of code, skip if it wouldn't produce any effects. |
| (...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1827 VisitVariableLoad(variable, slot, typeof_mode); | 1812 VisitVariableLoad(variable, slot, typeof_mode); |
| 1828 } | 1813 } |
| 1829 | 1814 |
| 1830 Register BytecodeGenerator::VisitVariableLoadForRegisterValue( | 1815 Register BytecodeGenerator::VisitVariableLoadForRegisterValue( |
| 1831 Variable* variable, FeedbackVectorSlot slot, TypeofMode typeof_mode) { | 1816 Variable* variable, FeedbackVectorSlot slot, TypeofMode typeof_mode) { |
| 1832 RegisterResultScope register_scope(this); | 1817 RegisterResultScope register_scope(this); |
| 1833 VisitVariableLoad(variable, slot, typeof_mode); | 1818 VisitVariableLoad(variable, slot, typeof_mode); |
| 1834 return register_scope.ResultRegister(); | 1819 return register_scope.ResultRegister(); |
| 1835 } | 1820 } |
| 1836 | 1821 |
| 1837 void BytecodeGenerator::PrepareNamedSuperPropertyArguments( | 1822 void BytecodeGenerator::BuildNamedSuperPropertyLoad(Register receiver, |
| 1838 SuperPropertyReference* super_property, Handle<Name> name, | 1823 Register home_object, |
| 1839 SuperPropertyArguments* super_args) { | 1824 Register name) { |
| 1840 register_allocator()->PrepareAndInitializeConsecutiveAllocations( | 1825 DCHECK(Register::AreContiguous(receiver, home_object, name)); |
| 1841 super_args->registers()); | 1826 builder()->CallRuntime(Runtime::kLoadFromSuper, receiver, 3); |
| 1842 | |
| 1843 VisitForAccumulatorValue(super_property->this_var()); | |
| 1844 builder()->StoreAccumulatorInRegister(super_args->receiver()); | |
| 1845 VisitForAccumulatorValue(super_property->home_object()); | |
| 1846 builder()->StoreAccumulatorInRegister(super_args->home_object()); | |
| 1847 builder()->LoadLiteral(name).StoreAccumulatorInRegister( | |
| 1848 super_args->name_or_key()); | |
| 1849 } | 1827 } |
| 1850 | 1828 |
| 1851 void BytecodeGenerator::PrepareKeyedSuperPropertyArguments( | 1829 void BytecodeGenerator::BuildKeyedSuperPropertyLoad(Register receiver, |
| 1852 SuperPropertyReference* super_property, Expression* key, | 1830 Register home_object, |
| 1853 SuperPropertyArguments* super_args) { | 1831 Register key) { |
| 1854 register_allocator()->PrepareAndInitializeConsecutiveAllocations( | 1832 DCHECK(Register::AreContiguous(receiver, home_object, key)); |
| 1855 super_args->registers()); | 1833 builder()->CallRuntime(Runtime::kLoadKeyedFromSuper, receiver, 3); |
| 1856 | |
| 1857 VisitForAccumulatorValue(super_property->this_var()); | |
| 1858 builder()->StoreAccumulatorInRegister(super_args->receiver()); | |
| 1859 VisitForAccumulatorValue(super_property->home_object()); | |
| 1860 builder()->StoreAccumulatorInRegister(super_args->home_object()); | |
| 1861 VisitForAccumulatorValue(key); | |
| 1862 builder()->StoreAccumulatorInRegister(super_args->name_or_key()); | |
| 1863 } | 1834 } |
| 1864 | 1835 |
| 1865 void BytecodeGenerator::BuildNamedSuperPropertyLoad( | 1836 void BytecodeGenerator::BuildNamedSuperPropertyStore(Register receiver, |
| 1866 SuperPropertyArguments* super_args) { | 1837 Register home_object, |
| 1867 // TODO(oth): Abstraction not suitable for 3 args, will over-allocate regs. | 1838 Register name, |
| 1868 builder()->CallRuntime(Runtime::kLoadFromSuper, super_args->receiver(), 3); | 1839 Register value) { |
| 1869 } | 1840 DCHECK(Register::AreContiguous(receiver, home_object, name, value)); |
| 1870 | |
| 1871 void BytecodeGenerator::BuildKeyedSuperPropertyLoad( | |
| 1872 SuperPropertyArguments* super_args) { | |
| 1873 // TODO(oth): Abstraction not suitable for 3 args, will over-allocate regs. | |
| 1874 builder()->CallRuntime(Runtime::kLoadKeyedFromSuper, super_args->receiver(), | |
| 1875 3); | |
| 1876 } | |
| 1877 | |
| 1878 void BytecodeGenerator::BuildNamedSuperPropertyStore( | |
| 1879 SuperPropertyArguments* super_args) { | |
| 1880 builder()->StoreAccumulatorInRegister(super_args->store_value()); | |
| 1881 Runtime::FunctionId function_id = is_strict(language_mode()) | 1841 Runtime::FunctionId function_id = is_strict(language_mode()) |
| 1882 ? Runtime::kStoreToSuper_Strict | 1842 ? Runtime::kStoreToSuper_Strict |
| 1883 : Runtime::kStoreToSuper_Sloppy; | 1843 : Runtime::kStoreToSuper_Sloppy; |
| 1884 builder()->CallRuntime(function_id, super_args->receiver(), | 1844 builder()->CallRuntime(function_id, receiver, 4); |
| 1885 super_args->count()); | |
| 1886 } | 1845 } |
| 1887 | 1846 |
| 1888 void BytecodeGenerator::BuildKeyedSuperPropertyStore( | 1847 void BytecodeGenerator::BuildKeyedSuperPropertyStore(Register receiver, |
| 1889 SuperPropertyArguments* super_args) { | 1848 Register home_object, |
| 1890 builder()->StoreAccumulatorInRegister(super_args->store_value()); | 1849 Register key, |
| 1850 Register value) { |
| 1851 DCHECK(Register::AreContiguous(receiver, home_object, key, value)); |
| 1891 Runtime::FunctionId function_id = is_strict(language_mode()) | 1852 Runtime::FunctionId function_id = is_strict(language_mode()) |
| 1892 ? Runtime::kStoreKeyedToSuper_Strict | 1853 ? Runtime::kStoreKeyedToSuper_Strict |
| 1893 : Runtime::kStoreKeyedToSuper_Sloppy; | 1854 : Runtime::kStoreKeyedToSuper_Sloppy; |
| 1894 builder()->CallRuntime(function_id, super_args->receiver(), | 1855 builder()->CallRuntime(function_id, receiver, 4); |
| 1895 super_args->count()); | |
| 1896 } | 1856 } |
| 1897 | 1857 |
| 1898 void BytecodeGenerator::BuildThrowReferenceError(Handle<String> name) { | 1858 void BytecodeGenerator::BuildThrowReferenceError(Handle<String> name) { |
| 1899 RegisterAllocationScope register_scope(this); | 1859 RegisterAllocationScope register_scope(this); |
| 1900 Register name_reg = register_allocator()->NewRegister(); | 1860 Register name_reg = register_allocator()->NewRegister(); |
| 1901 builder()->LoadLiteral(name).StoreAccumulatorInRegister(name_reg).CallRuntime( | 1861 builder()->LoadLiteral(name).StoreAccumulatorInRegister(name_reg).CallRuntime( |
| 1902 Runtime::kThrowReferenceError, name_reg, 1); | 1862 Runtime::kThrowReferenceError, name_reg, 1); |
| 1903 } | 1863 } |
| 1904 | 1864 |
| 1905 void BytecodeGenerator::BuildThrowIfHole(Handle<String> name) { | 1865 void BytecodeGenerator::BuildThrowIfHole(Handle<String> name) { |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2096 builder()->StoreLookupSlot(variable->name(), language_mode()); | 2056 builder()->StoreLookupSlot(variable->name(), language_mode()); |
| 2097 } | 2057 } |
| 2098 break; | 2058 break; |
| 2099 } | 2059 } |
| 2100 } | 2060 } |
| 2101 } | 2061 } |
| 2102 | 2062 |
| 2103 | 2063 |
| 2104 void BytecodeGenerator::VisitAssignment(Assignment* expr) { | 2064 void BytecodeGenerator::VisitAssignment(Assignment* expr) { |
| 2105 DCHECK(expr->target()->IsValidReferenceExpressionOrThis()); | 2065 DCHECK(expr->target()->IsValidReferenceExpressionOrThis()); |
| 2106 Register object, key; | 2066 Register object, key, home_object, value; |
| 2107 SuperPropertyArguments super_args; | |
| 2108 Handle<String> name; | 2067 Handle<String> name; |
| 2109 | 2068 |
| 2110 // Left-hand side can only be a property, a global or a variable slot. | 2069 // Left-hand side can only be a property, a global or a variable slot. |
| 2111 Property* property = expr->target()->AsProperty(); | 2070 Property* property = expr->target()->AsProperty(); |
| 2112 LhsKind assign_type = Property::GetAssignType(property); | 2071 LhsKind assign_type = Property::GetAssignType(property); |
| 2113 | 2072 |
| 2114 // Evaluate LHS expression. | 2073 // Evaluate LHS expression. |
| 2115 switch (assign_type) { | 2074 switch (assign_type) { |
| 2116 case VARIABLE: | 2075 case VARIABLE: |
| 2117 // Nothing to do to evaluate variable assignment LHS. | 2076 // Nothing to do to evaluate variable assignment LHS. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2128 // still in the accumulator for loading the old value below. | 2087 // still in the accumulator for loading the old value below. |
| 2129 key = register_allocator()->NewRegister(); | 2088 key = register_allocator()->NewRegister(); |
| 2130 VisitForAccumulatorValue(property->key()); | 2089 VisitForAccumulatorValue(property->key()); |
| 2131 builder()->StoreAccumulatorInRegister(key); | 2090 builder()->StoreAccumulatorInRegister(key); |
| 2132 } else { | 2091 } else { |
| 2133 key = VisitForRegisterValue(property->key()); | 2092 key = VisitForRegisterValue(property->key()); |
| 2134 } | 2093 } |
| 2135 break; | 2094 break; |
| 2136 } | 2095 } |
| 2137 case NAMED_SUPER_PROPERTY: { | 2096 case NAMED_SUPER_PROPERTY: { |
| 2138 PrepareNamedSuperPropertyArguments( | 2097 register_allocator()->PrepareForConsecutiveAllocations(4); |
| 2139 property->obj()->AsSuperPropertyReference(), | 2098 object = register_allocator()->NextConsecutiveRegister(); |
| 2140 property->key()->AsLiteral()->AsPropertyName(), &super_args); | 2099 home_object = register_allocator()->NextConsecutiveRegister(); |
| 2100 key = register_allocator()->NextConsecutiveRegister(); |
| 2101 value = register_allocator()->NextConsecutiveRegister(); |
| 2102 SuperPropertyReference* super_property = |
| 2103 property->obj()->AsSuperPropertyReference(); |
| 2104 VisitForRegisterValue(super_property->this_var(), object); |
| 2105 VisitForRegisterValue(super_property->home_object(), home_object); |
| 2106 builder() |
| 2107 ->LoadLiteral(property->key()->AsLiteral()->AsPropertyName()) |
| 2108 .StoreAccumulatorInRegister(key); |
| 2141 break; | 2109 break; |
| 2142 } | 2110 } |
| 2143 case KEYED_SUPER_PROPERTY: { | 2111 case KEYED_SUPER_PROPERTY: { |
| 2144 PrepareKeyedSuperPropertyArguments( | 2112 register_allocator()->PrepareForConsecutiveAllocations(4); |
| 2145 property->obj()->AsSuperPropertyReference(), property->key(), | 2113 object = register_allocator()->NextConsecutiveRegister(); |
| 2146 &super_args); | 2114 home_object = register_allocator()->NextConsecutiveRegister(); |
| 2115 key = register_allocator()->NextConsecutiveRegister(); |
| 2116 value = register_allocator()->NextConsecutiveRegister(); |
| 2117 builder()->StoreAccumulatorInRegister(value); |
| 2118 SuperPropertyReference* super_property = |
| 2119 property->obj()->AsSuperPropertyReference(); |
| 2120 VisitForRegisterValue(super_property->this_var(), object); |
| 2121 VisitForRegisterValue(super_property->home_object(), home_object); |
| 2122 VisitForRegisterValue(property->key(), key); |
| 2147 break; | 2123 break; |
| 2148 } | 2124 } |
| 2149 } | 2125 } |
| 2150 | 2126 |
| 2151 // Evaluate the value and potentially handle compound assignments by loading | 2127 // Evaluate the value and potentially handle compound assignments by loading |
| 2152 // the left-hand side value and performing a binary operation. | 2128 // the left-hand side value and performing a binary operation. |
| 2153 if (expr->is_compound()) { | 2129 if (expr->is_compound()) { |
| 2154 Register old_value; | 2130 Register old_value; |
| 2155 switch (assign_type) { | 2131 switch (assign_type) { |
| 2156 case VARIABLE: { | 2132 case VARIABLE: { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2172 // LHS above. | 2148 // LHS above. |
| 2173 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); | 2149 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); |
| 2174 old_value = register_allocator()->NewRegister(); | 2150 old_value = register_allocator()->NewRegister(); |
| 2175 builder() | 2151 builder() |
| 2176 ->LoadKeyedProperty(object, feedback_index(slot)) | 2152 ->LoadKeyedProperty(object, feedback_index(slot)) |
| 2177 .StoreAccumulatorInRegister(old_value); | 2153 .StoreAccumulatorInRegister(old_value); |
| 2178 break; | 2154 break; |
| 2179 } | 2155 } |
| 2180 case NAMED_SUPER_PROPERTY: { | 2156 case NAMED_SUPER_PROPERTY: { |
| 2181 old_value = register_allocator()->NewRegister(); | 2157 old_value = register_allocator()->NewRegister(); |
| 2182 BuildNamedSuperPropertyLoad(&super_args); | 2158 BuildNamedSuperPropertyLoad(object, home_object, key); |
| 2183 builder()->StoreAccumulatorInRegister(old_value); | 2159 builder()->StoreAccumulatorInRegister(old_value); |
| 2184 break; | 2160 break; |
| 2185 } | 2161 } |
| 2186 case KEYED_SUPER_PROPERTY: { | 2162 case KEYED_SUPER_PROPERTY: { |
| 2187 old_value = register_allocator()->NewRegister(); | 2163 old_value = register_allocator()->NewRegister(); |
| 2188 BuildKeyedSuperPropertyLoad(&super_args); | 2164 BuildKeyedSuperPropertyLoad(object, home_object, key); |
| 2189 builder()->StoreAccumulatorInRegister(old_value); | 2165 builder()->StoreAccumulatorInRegister(old_value); |
| 2190 break; | 2166 break; |
| 2191 } | 2167 } |
| 2192 } | 2168 } |
| 2193 VisitForAccumulatorValue(expr->value()); | 2169 VisitForAccumulatorValue(expr->value()); |
| 2194 builder()->BinaryOperation(expr->binary_op(), old_value); | 2170 builder()->BinaryOperation(expr->binary_op(), old_value); |
| 2195 } else { | 2171 } else { |
| 2196 VisitForAccumulatorValue(expr->value()); | 2172 VisitForAccumulatorValue(expr->value()); |
| 2197 } | 2173 } |
| 2198 | 2174 |
| 2199 // Store the value. | 2175 // Store the value. |
| 2200 FeedbackVectorSlot slot = expr->AssignmentSlot(); | 2176 FeedbackVectorSlot slot = expr->AssignmentSlot(); |
| 2201 switch (assign_type) { | 2177 switch (assign_type) { |
| 2202 case VARIABLE: { | 2178 case VARIABLE: { |
| 2203 // TODO(oth): The VisitVariableAssignment() call is hard to reason about. | 2179 // TODO(oth): The VisitVariableAssignment() call is hard to reason about. |
| 2204 // Is the value in the accumulator safe? Yes, but scary. | 2180 // Is the value in the accumulator safe? Yes, but scary. |
| 2205 Variable* variable = expr->target()->AsVariableProxy()->var(); | 2181 Variable* variable = expr->target()->AsVariableProxy()->var(); |
| 2206 VisitVariableAssignment(variable, expr->op(), slot); | 2182 VisitVariableAssignment(variable, expr->op(), slot); |
| 2207 break; | 2183 break; |
| 2208 } | 2184 } |
| 2209 case NAMED_PROPERTY: | 2185 case NAMED_PROPERTY: |
| 2210 builder()->StoreNamedProperty(object, name, feedback_index(slot), | 2186 builder()->StoreNamedProperty(object, name, feedback_index(slot), |
| 2211 language_mode()); | 2187 language_mode()); |
| 2212 break; | 2188 break; |
| 2213 case KEYED_PROPERTY: | 2189 case KEYED_PROPERTY: |
| 2214 builder()->StoreKeyedProperty(object, key, feedback_index(slot), | 2190 builder()->StoreKeyedProperty(object, key, feedback_index(slot), |
| 2215 language_mode()); | 2191 language_mode()); |
| 2216 break; | 2192 break; |
| 2217 case NAMED_SUPER_PROPERTY: { | 2193 case NAMED_SUPER_PROPERTY: { |
| 2218 BuildNamedSuperPropertyStore(&super_args); | 2194 builder()->StoreAccumulatorInRegister(value); |
| 2195 BuildNamedSuperPropertyStore(object, home_object, key, value); |
| 2219 break; | 2196 break; |
| 2220 } | 2197 } |
| 2221 case KEYED_SUPER_PROPERTY: { | 2198 case KEYED_SUPER_PROPERTY: { |
| 2222 BuildKeyedSuperPropertyStore(&super_args); | 2199 builder()->StoreAccumulatorInRegister(value); |
| 2200 BuildKeyedSuperPropertyStore(object, home_object, key, value); |
| 2223 break; | 2201 break; |
| 2224 } | 2202 } |
| 2225 } | 2203 } |
| 2226 execution_result()->SetResultInAccumulator(); | 2204 execution_result()->SetResultInAccumulator(); |
| 2227 } | 2205 } |
| 2228 | 2206 |
| 2229 | 2207 |
| 2230 void BytecodeGenerator::VisitYield(Yield* expr) { UNIMPLEMENTED(); } | 2208 void BytecodeGenerator::VisitYield(Yield* expr) { UNIMPLEMENTED(); } |
| 2231 | 2209 |
| 2232 | 2210 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2270 | 2248 |
| 2271 void BytecodeGenerator::VisitPropertyLoadForAccumulator(Register obj, | 2249 void BytecodeGenerator::VisitPropertyLoadForAccumulator(Register obj, |
| 2272 Property* expr) { | 2250 Property* expr) { |
| 2273 AccumulatorResultScope result_scope(this); | 2251 AccumulatorResultScope result_scope(this); |
| 2274 VisitPropertyLoad(obj, expr); | 2252 VisitPropertyLoad(obj, expr); |
| 2275 } | 2253 } |
| 2276 | 2254 |
| 2277 void BytecodeGenerator::VisitNamedSuperPropertyLoad(Property* property, | 2255 void BytecodeGenerator::VisitNamedSuperPropertyLoad(Property* property, |
| 2278 Register opt_receiver_out) { | 2256 Register opt_receiver_out) { |
| 2279 RegisterAllocationScope register_scope(this); | 2257 RegisterAllocationScope register_scope(this); |
| 2280 SuperPropertyArguments super_args; | 2258 register_allocator()->PrepareForConsecutiveAllocations(3); |
| 2281 PrepareNamedSuperPropertyArguments( | 2259 |
| 2282 property->obj()->AsSuperPropertyReference(), | 2260 Register receiver, home_object, name; |
| 2283 property->key()->AsLiteral()->AsPropertyName(), &super_args); | 2261 receiver = register_allocator()->NextConsecutiveRegister(); |
| 2262 home_object = register_allocator()->NextConsecutiveRegister(); |
| 2263 name = register_allocator()->NextConsecutiveRegister(); |
| 2264 SuperPropertyReference* super_property = |
| 2265 property->obj()->AsSuperPropertyReference(); |
| 2266 VisitForRegisterValue(super_property->this_var(), receiver); |
| 2267 VisitForRegisterValue(super_property->home_object(), home_object); |
| 2268 builder() |
| 2269 ->LoadLiteral(property->key()->AsLiteral()->AsPropertyName()) |
| 2270 .StoreAccumulatorInRegister(name); |
| 2271 BuildNamedSuperPropertyLoad(receiver, home_object, name); |
| 2272 |
| 2284 if (opt_receiver_out.is_valid()) { | 2273 if (opt_receiver_out.is_valid()) { |
| 2285 builder()->MoveRegister(super_args.receiver(), opt_receiver_out); | 2274 builder()->MoveRegister(receiver, opt_receiver_out); |
| 2286 } | 2275 } |
| 2287 BuildNamedSuperPropertyLoad(&super_args); | |
| 2288 } | 2276 } |
| 2289 | 2277 |
| 2290 void BytecodeGenerator::VisitKeyedSuperPropertyLoad(Property* property, | 2278 void BytecodeGenerator::VisitKeyedSuperPropertyLoad(Property* property, |
| 2291 Register opt_receiver_out) { | 2279 Register opt_receiver_out) { |
| 2292 RegisterAllocationScope register_scope(this); | 2280 RegisterAllocationScope register_scope(this); |
| 2293 SuperPropertyArguments super_args; | 2281 register_allocator()->PrepareForConsecutiveAllocations(3); |
| 2294 PrepareKeyedSuperPropertyArguments( | 2282 |
| 2295 property->obj()->AsSuperPropertyReference(), property->key(), | 2283 Register receiver, home_object, key; |
| 2296 &super_args); | 2284 receiver = register_allocator()->NextConsecutiveRegister(); |
| 2285 home_object = register_allocator()->NextConsecutiveRegister(); |
| 2286 key = register_allocator()->NextConsecutiveRegister(); |
| 2287 SuperPropertyReference* super_property = |
| 2288 property->obj()->AsSuperPropertyReference(); |
| 2289 VisitForRegisterValue(super_property->this_var(), receiver); |
| 2290 VisitForRegisterValue(super_property->home_object(), home_object); |
| 2291 VisitForRegisterValue(property->key(), key); |
| 2292 BuildKeyedSuperPropertyLoad(receiver, home_object, key); |
| 2293 |
| 2297 if (opt_receiver_out.is_valid()) { | 2294 if (opt_receiver_out.is_valid()) { |
| 2298 builder()->MoveRegister(super_args.receiver(), opt_receiver_out); | 2295 builder()->MoveRegister(receiver, opt_receiver_out); |
| 2299 } | 2296 } |
| 2300 BuildKeyedSuperPropertyLoad(&super_args); | |
| 2301 } | 2297 } |
| 2302 | 2298 |
| 2303 void BytecodeGenerator::VisitProperty(Property* expr) { | 2299 void BytecodeGenerator::VisitProperty(Property* expr) { |
| 2304 LhsKind property_kind = Property::GetAssignType(expr); | 2300 LhsKind property_kind = Property::GetAssignType(expr); |
| 2305 if (property_kind != NAMED_SUPER_PROPERTY && | 2301 if (property_kind != NAMED_SUPER_PROPERTY && |
| 2306 property_kind != KEYED_SUPER_PROPERTY) { | 2302 property_kind != KEYED_SUPER_PROPERTY) { |
| 2307 Register obj = VisitForRegisterValue(expr->obj()); | 2303 Register obj = VisitForRegisterValue(expr->obj()); |
| 2308 VisitPropertyLoad(obj, expr); | 2304 VisitPropertyLoad(obj, expr); |
| 2309 } else { | 2305 } else { |
| 2310 VisitPropertyLoad(Register::invalid_value(), expr); | 2306 VisitPropertyLoad(Register::invalid_value(), expr); |
| (...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2654 DCHECK(expr->expression()->IsValidReferenceExpressionOrThis()); | 2650 DCHECK(expr->expression()->IsValidReferenceExpressionOrThis()); |
| 2655 | 2651 |
| 2656 // Left-hand side can only be a property, a global or a variable slot. | 2652 // Left-hand side can only be a property, a global or a variable slot. |
| 2657 Property* property = expr->expression()->AsProperty(); | 2653 Property* property = expr->expression()->AsProperty(); |
| 2658 LhsKind assign_type = Property::GetAssignType(property); | 2654 LhsKind assign_type = Property::GetAssignType(property); |
| 2659 | 2655 |
| 2660 // TODO(rmcilroy): Set is_postfix to false if visiting for effect. | 2656 // TODO(rmcilroy): Set is_postfix to false if visiting for effect. |
| 2661 bool is_postfix = expr->is_postfix(); | 2657 bool is_postfix = expr->is_postfix(); |
| 2662 | 2658 |
| 2663 // Evaluate LHS expression and get old value. | 2659 // Evaluate LHS expression and get old value. |
| 2664 Register object, key, old_value; | 2660 Register object, home_object, key, old_value, value; |
| 2665 SuperPropertyArguments super_args; | |
| 2666 Handle<String> name; | 2661 Handle<String> name; |
| 2667 switch (assign_type) { | 2662 switch (assign_type) { |
| 2668 case VARIABLE: { | 2663 case VARIABLE: { |
| 2669 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 2664 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
| 2670 VisitVariableLoadForAccumulatorValue(proxy->var(), | 2665 VisitVariableLoadForAccumulatorValue(proxy->var(), |
| 2671 proxy->VariableFeedbackSlot()); | 2666 proxy->VariableFeedbackSlot()); |
| 2672 break; | 2667 break; |
| 2673 } | 2668 } |
| 2674 case NAMED_PROPERTY: { | 2669 case NAMED_PROPERTY: { |
| 2675 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); | 2670 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); |
| 2676 object = VisitForRegisterValue(property->obj()); | 2671 object = VisitForRegisterValue(property->obj()); |
| 2677 name = property->key()->AsLiteral()->AsPropertyName(); | 2672 name = property->key()->AsLiteral()->AsPropertyName(); |
| 2678 builder()->LoadNamedProperty(object, name, feedback_index(slot)); | 2673 builder()->LoadNamedProperty(object, name, feedback_index(slot)); |
| 2679 break; | 2674 break; |
| 2680 } | 2675 } |
| 2681 case KEYED_PROPERTY: { | 2676 case KEYED_PROPERTY: { |
| 2682 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); | 2677 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); |
| 2683 object = VisitForRegisterValue(property->obj()); | 2678 object = VisitForRegisterValue(property->obj()); |
| 2684 // Use visit for accumulator here since we need the key in the accumulator | 2679 // Use visit for accumulator here since we need the key in the accumulator |
| 2685 // for the LoadKeyedProperty. | 2680 // for the LoadKeyedProperty. |
| 2686 key = register_allocator()->NewRegister(); | 2681 key = register_allocator()->NewRegister(); |
| 2687 VisitForAccumulatorValue(property->key()); | 2682 VisitForAccumulatorValue(property->key()); |
| 2688 builder()->StoreAccumulatorInRegister(key).LoadKeyedProperty( | 2683 builder()->StoreAccumulatorInRegister(key).LoadKeyedProperty( |
| 2689 object, feedback_index(slot)); | 2684 object, feedback_index(slot)); |
| 2690 break; | 2685 break; |
| 2691 } | 2686 } |
| 2692 case NAMED_SUPER_PROPERTY: { | 2687 case NAMED_SUPER_PROPERTY: { |
| 2693 PrepareNamedSuperPropertyArguments( | 2688 register_allocator()->PrepareForConsecutiveAllocations(4); |
| 2694 property->obj()->AsSuperPropertyReference(), | 2689 object = register_allocator()->NextConsecutiveRegister(); |
| 2695 property->key()->AsLiteral()->AsPropertyName(), &super_args); | 2690 home_object = register_allocator()->NextConsecutiveRegister(); |
| 2696 BuildNamedSuperPropertyLoad(&super_args); | 2691 key = register_allocator()->NextConsecutiveRegister(); |
| 2692 value = register_allocator()->NextConsecutiveRegister(); |
| 2693 SuperPropertyReference* super_property = |
| 2694 property->obj()->AsSuperPropertyReference(); |
| 2695 VisitForRegisterValue(super_property->this_var(), object); |
| 2696 VisitForRegisterValue(super_property->home_object(), home_object); |
| 2697 builder() |
| 2698 ->LoadLiteral(property->key()->AsLiteral()->AsPropertyName()) |
| 2699 .StoreAccumulatorInRegister(key); |
| 2700 BuildNamedSuperPropertyLoad(object, home_object, key); |
| 2697 break; | 2701 break; |
| 2698 } | 2702 } |
| 2699 case KEYED_SUPER_PROPERTY: { | 2703 case KEYED_SUPER_PROPERTY: { |
| 2700 PrepareKeyedSuperPropertyArguments( | 2704 register_allocator()->PrepareForConsecutiveAllocations(4); |
| 2701 property->obj()->AsSuperPropertyReference(), property->key(), | 2705 object = register_allocator()->NextConsecutiveRegister(); |
| 2702 &super_args); | 2706 home_object = register_allocator()->NextConsecutiveRegister(); |
| 2703 BuildKeyedSuperPropertyLoad(&super_args); | 2707 key = register_allocator()->NextConsecutiveRegister(); |
| 2708 value = register_allocator()->NextConsecutiveRegister(); |
| 2709 builder()->StoreAccumulatorInRegister(value); |
| 2710 SuperPropertyReference* super_property = |
| 2711 property->obj()->AsSuperPropertyReference(); |
| 2712 VisitForRegisterValue(super_property->this_var(), object); |
| 2713 VisitForRegisterValue(super_property->home_object(), home_object); |
| 2714 VisitForRegisterValue(property->key(), key); |
| 2715 BuildKeyedSuperPropertyLoad(object, home_object, key); |
| 2704 break; | 2716 break; |
| 2705 } | 2717 } |
| 2706 } | 2718 } |
| 2707 | 2719 |
| 2708 // Convert old value into a number. | 2720 // Convert old value into a number. |
| 2709 if (!is_strong(language_mode())) { | 2721 if (!is_strong(language_mode())) { |
| 2710 builder()->CastAccumulatorToNumber(); | 2722 builder()->CastAccumulatorToNumber(); |
| 2711 } | 2723 } |
| 2712 | 2724 |
| 2713 // Save result for postfix expressions. | 2725 // Save result for postfix expressions. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2731 builder()->StoreNamedProperty(object, name, feedback_index(feedback_slot), | 2743 builder()->StoreNamedProperty(object, name, feedback_index(feedback_slot), |
| 2732 language_mode()); | 2744 language_mode()); |
| 2733 break; | 2745 break; |
| 2734 } | 2746 } |
| 2735 case KEYED_PROPERTY: { | 2747 case KEYED_PROPERTY: { |
| 2736 builder()->StoreKeyedProperty(object, key, feedback_index(feedback_slot), | 2748 builder()->StoreKeyedProperty(object, key, feedback_index(feedback_slot), |
| 2737 language_mode()); | 2749 language_mode()); |
| 2738 break; | 2750 break; |
| 2739 } | 2751 } |
| 2740 case NAMED_SUPER_PROPERTY: { | 2752 case NAMED_SUPER_PROPERTY: { |
| 2741 BuildNamedSuperPropertyStore(&super_args); | 2753 builder()->StoreAccumulatorInRegister(value); |
| 2754 BuildNamedSuperPropertyStore(object, home_object, key, value); |
| 2742 break; | 2755 break; |
| 2743 } | 2756 } |
| 2744 case KEYED_SUPER_PROPERTY: { | 2757 case KEYED_SUPER_PROPERTY: { |
| 2745 BuildKeyedSuperPropertyStore(&super_args); | 2758 builder()->StoreAccumulatorInRegister(value); |
| 2759 BuildKeyedSuperPropertyStore(object, home_object, key, value); |
| 2746 break; | 2760 break; |
| 2747 } | 2761 } |
| 2748 } | 2762 } |
| 2749 | 2763 |
| 2750 // Restore old value for postfix expressions. | 2764 // Restore old value for postfix expressions. |
| 2751 if (is_postfix) { | 2765 if (is_postfix) { |
| 2752 execution_result()->SetResultInRegister(old_value); | 2766 execution_result()->SetResultInRegister(old_value); |
| 2753 } else { | 2767 } else { |
| 2754 execution_result()->SetResultInAccumulator(); | 2768 execution_result()->SetResultInAccumulator(); |
| 2755 } | 2769 } |
| (...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3091 | 3105 |
| 3092 | 3106 |
| 3093 // Visits the expression |expr| and returns the register containing | 3107 // Visits the expression |expr| and returns the register containing |
| 3094 // the expression result. | 3108 // the expression result. |
| 3095 Register BytecodeGenerator::VisitForRegisterValue(Expression* expr) { | 3109 Register BytecodeGenerator::VisitForRegisterValue(Expression* expr) { |
| 3096 RegisterResultScope register_scope(this); | 3110 RegisterResultScope register_scope(this); |
| 3097 Visit(expr); | 3111 Visit(expr); |
| 3098 return register_scope.ResultRegister(); | 3112 return register_scope.ResultRegister(); |
| 3099 } | 3113 } |
| 3100 | 3114 |
| 3115 // Visits the expression |expr| and stores the expression result in |
| 3116 // |destination|. |
| 3117 void BytecodeGenerator::VisitForRegisterValue(Expression* expr, |
| 3118 Register destination) { |
| 3119 AccumulatorResultScope register_scope(this); |
| 3120 Visit(expr); |
| 3121 builder()->StoreAccumulatorInRegister(destination); |
| 3122 } |
| 3101 | 3123 |
| 3102 void BytecodeGenerator::VisitInScope(Statement* stmt, Scope* scope) { | 3124 void BytecodeGenerator::VisitInScope(Statement* stmt, Scope* scope) { |
| 3103 ContextScope context_scope(this, scope); | 3125 ContextScope context_scope(this, scope); |
| 3104 DCHECK(scope->declarations()->is_empty()); | 3126 DCHECK(scope->declarations()->is_empty()); |
| 3105 Visit(stmt); | 3127 Visit(stmt); |
| 3106 } | 3128 } |
| 3107 | 3129 |
| 3108 | 3130 |
| 3109 LanguageMode BytecodeGenerator::language_mode() const { | 3131 LanguageMode BytecodeGenerator::language_mode() const { |
| 3110 return info()->language_mode(); | 3132 return info()->language_mode(); |
| 3111 } | 3133 } |
| 3112 | 3134 |
| 3113 | 3135 |
| 3114 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 3136 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
| 3115 return info()->feedback_vector()->GetIndex(slot); | 3137 return info()->feedback_vector()->GetIndex(slot); |
| 3116 } | 3138 } |
| 3117 | 3139 |
| 3118 } // namespace interpreter | 3140 } // namespace interpreter |
| 3119 } // namespace internal | 3141 } // namespace internal |
| 3120 } // namespace v8 | 3142 } // namespace v8 |
| OLD | NEW |