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); | |
rmcilroy
2016/02/22 20:45:10
Could you pass the other registers as arguments to
| |
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); | |
rmcilroy
2016/02/22 20:45:10
Ditto (and for the others).
| |
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 builder()->CallRuntime(Runtime::kLoadFromSuper, receiver, 3); |
1839 SuperPropertyArguments* super_args) { | |
1840 register_allocator()->PrepareAndInitializeConsecutiveAllocations( | |
1841 super_args->registers()); | |
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 } | 1824 } |
1850 | 1825 |
1851 void BytecodeGenerator::PrepareKeyedSuperPropertyArguments( | 1826 void BytecodeGenerator::BuildKeyedSuperPropertyLoad(Register receiver) { |
1852 SuperPropertyReference* super_property, Expression* key, | 1827 builder()->CallRuntime(Runtime::kLoadKeyedFromSuper, receiver, 3); |
1853 SuperPropertyArguments* super_args) { | |
1854 register_allocator()->PrepareAndInitializeConsecutiveAllocations( | |
1855 super_args->registers()); | |
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 } | 1828 } |
1864 | 1829 |
1865 void BytecodeGenerator::BuildNamedSuperPropertyLoad( | 1830 void BytecodeGenerator::BuildNamedSuperPropertyStore(Register receiver) { |
1866 SuperPropertyArguments* super_args) { | |
1867 // TODO(oth): Abstraction not suitable for 3 args, will over-allocate regs. | |
1868 builder()->CallRuntime(Runtime::kLoadFromSuper, super_args->receiver(), 3); | |
1869 } | |
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()) | 1831 Runtime::FunctionId function_id = is_strict(language_mode()) |
1882 ? Runtime::kStoreToSuper_Strict | 1832 ? Runtime::kStoreToSuper_Strict |
1883 : Runtime::kStoreToSuper_Sloppy; | 1833 : Runtime::kStoreToSuper_Sloppy; |
1884 builder()->CallRuntime(function_id, super_args->receiver(), | 1834 builder()->CallRuntime(function_id, receiver, 4); |
1885 super_args->count()); | |
1886 } | 1835 } |
1887 | 1836 |
1888 void BytecodeGenerator::BuildKeyedSuperPropertyStore( | 1837 void BytecodeGenerator::BuildKeyedSuperPropertyStore(Register receiver) { |
1889 SuperPropertyArguments* super_args) { | |
1890 builder()->StoreAccumulatorInRegister(super_args->store_value()); | |
1891 Runtime::FunctionId function_id = is_strict(language_mode()) | 1838 Runtime::FunctionId function_id = is_strict(language_mode()) |
1892 ? Runtime::kStoreKeyedToSuper_Strict | 1839 ? Runtime::kStoreKeyedToSuper_Strict |
1893 : Runtime::kStoreKeyedToSuper_Sloppy; | 1840 : Runtime::kStoreKeyedToSuper_Sloppy; |
1894 builder()->CallRuntime(function_id, super_args->receiver(), | 1841 builder()->CallRuntime(function_id, receiver, 4); |
1895 super_args->count()); | |
1896 } | 1842 } |
1897 | 1843 |
1898 void BytecodeGenerator::BuildThrowReferenceError(Handle<String> name) { | 1844 void BytecodeGenerator::BuildThrowReferenceError(Handle<String> name) { |
1899 RegisterAllocationScope register_scope(this); | 1845 RegisterAllocationScope register_scope(this); |
1900 Register name_reg = register_allocator()->NewRegister(); | 1846 Register name_reg = register_allocator()->NewRegister(); |
1901 builder()->LoadLiteral(name).StoreAccumulatorInRegister(name_reg).CallRuntime( | 1847 builder()->LoadLiteral(name).StoreAccumulatorInRegister(name_reg).CallRuntime( |
1902 Runtime::kThrowReferenceError, name_reg, 1); | 1848 Runtime::kThrowReferenceError, name_reg, 1); |
1903 } | 1849 } |
1904 | 1850 |
1905 void BytecodeGenerator::BuildThrowIfHole(Handle<String> name) { | 1851 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()); | 2042 builder()->StoreLookupSlot(variable->name(), language_mode()); |
2097 } | 2043 } |
2098 break; | 2044 break; |
2099 } | 2045 } |
2100 } | 2046 } |
2101 } | 2047 } |
2102 | 2048 |
2103 | 2049 |
2104 void BytecodeGenerator::VisitAssignment(Assignment* expr) { | 2050 void BytecodeGenerator::VisitAssignment(Assignment* expr) { |
2105 DCHECK(expr->target()->IsValidReferenceExpressionOrThis()); | 2051 DCHECK(expr->target()->IsValidReferenceExpressionOrThis()); |
2106 Register object, key; | 2052 Register object, key, home_object, value; |
2107 SuperPropertyArguments super_args; | |
2108 Handle<String> name; | 2053 Handle<String> name; |
2109 | 2054 |
2110 // Left-hand side can only be a property, a global or a variable slot. | 2055 // Left-hand side can only be a property, a global or a variable slot. |
2111 Property* property = expr->target()->AsProperty(); | 2056 Property* property = expr->target()->AsProperty(); |
2112 LhsKind assign_type = Property::GetAssignType(property); | 2057 LhsKind assign_type = Property::GetAssignType(property); |
2113 | 2058 |
2114 // Evaluate LHS expression. | 2059 // Evaluate LHS expression. |
2115 switch (assign_type) { | 2060 switch (assign_type) { |
2116 case VARIABLE: | 2061 case VARIABLE: |
2117 // Nothing to do to evaluate variable assignment LHS. | 2062 // 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. | 2073 // still in the accumulator for loading the old value below. |
2129 key = register_allocator()->NewRegister(); | 2074 key = register_allocator()->NewRegister(); |
2130 VisitForAccumulatorValue(property->key()); | 2075 VisitForAccumulatorValue(property->key()); |
2131 builder()->StoreAccumulatorInRegister(key); | 2076 builder()->StoreAccumulatorInRegister(key); |
2132 } else { | 2077 } else { |
2133 key = VisitForRegisterValue(property->key()); | 2078 key = VisitForRegisterValue(property->key()); |
2134 } | 2079 } |
2135 break; | 2080 break; |
2136 } | 2081 } |
2137 case NAMED_SUPER_PROPERTY: { | 2082 case NAMED_SUPER_PROPERTY: { |
2138 PrepareNamedSuperPropertyArguments( | 2083 register_allocator()->PrepareForConsecutiveAllocations(4); |
2139 property->obj()->AsSuperPropertyReference(), | 2084 object = register_allocator()->NextConsecutiveRegister(); |
2140 property->key()->AsLiteral()->AsPropertyName(), &super_args); | 2085 home_object = register_allocator()->NextConsecutiveRegister(); |
2086 key = register_allocator()->NextConsecutiveRegister(); | |
2087 value = register_allocator()->NextConsecutiveRegister(); | |
2088 SuperPropertyReference* super_property = | |
2089 property->obj()->AsSuperPropertyReference(); | |
2090 VisitForRegisterValue(super_property->this_var(), object); | |
2091 VisitForRegisterValue(super_property->home_object(), home_object); | |
2092 builder() | |
2093 ->LoadLiteral(property->key()->AsLiteral()->AsPropertyName()) | |
2094 .StoreAccumulatorInRegister(key); | |
2141 break; | 2095 break; |
2142 } | 2096 } |
2143 case KEYED_SUPER_PROPERTY: { | 2097 case KEYED_SUPER_PROPERTY: { |
2144 PrepareKeyedSuperPropertyArguments( | 2098 register_allocator()->PrepareForConsecutiveAllocations(4); |
2145 property->obj()->AsSuperPropertyReference(), property->key(), | 2099 object = register_allocator()->NextConsecutiveRegister(); |
2146 &super_args); | 2100 home_object = register_allocator()->NextConsecutiveRegister(); |
2101 key = register_allocator()->NextConsecutiveRegister(); | |
2102 value = register_allocator()->NextConsecutiveRegister(); | |
2103 builder()->StoreAccumulatorInRegister(value); | |
2104 SuperPropertyReference* super_property = | |
2105 property->obj()->AsSuperPropertyReference(); | |
2106 VisitForRegisterValue(super_property->this_var(), object); | |
2107 VisitForRegisterValue(super_property->home_object(), home_object); | |
2108 VisitForRegisterValue(property->key(), key); | |
2147 break; | 2109 break; |
2148 } | 2110 } |
2149 } | 2111 } |
2150 | 2112 |
2151 // Evaluate the value and potentially handle compound assignments by loading | 2113 // Evaluate the value and potentially handle compound assignments by loading |
2152 // the left-hand side value and performing a binary operation. | 2114 // the left-hand side value and performing a binary operation. |
2153 if (expr->is_compound()) { | 2115 if (expr->is_compound()) { |
2154 Register old_value; | 2116 Register old_value; |
2155 switch (assign_type) { | 2117 switch (assign_type) { |
2156 case VARIABLE: { | 2118 case VARIABLE: { |
(...skipping 15 matching lines...) Expand all Loading... | |
2172 // LHS above. | 2134 // LHS above. |
2173 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); | 2135 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); |
2174 old_value = register_allocator()->NewRegister(); | 2136 old_value = register_allocator()->NewRegister(); |
2175 builder() | 2137 builder() |
2176 ->LoadKeyedProperty(object, feedback_index(slot)) | 2138 ->LoadKeyedProperty(object, feedback_index(slot)) |
2177 .StoreAccumulatorInRegister(old_value); | 2139 .StoreAccumulatorInRegister(old_value); |
2178 break; | 2140 break; |
2179 } | 2141 } |
2180 case NAMED_SUPER_PROPERTY: { | 2142 case NAMED_SUPER_PROPERTY: { |
2181 old_value = register_allocator()->NewRegister(); | 2143 old_value = register_allocator()->NewRegister(); |
2182 BuildNamedSuperPropertyLoad(&super_args); | 2144 BuildNamedSuperPropertyLoad(object); |
2183 builder()->StoreAccumulatorInRegister(old_value); | 2145 builder()->StoreAccumulatorInRegister(old_value); |
2184 break; | 2146 break; |
2185 } | 2147 } |
2186 case KEYED_SUPER_PROPERTY: { | 2148 case KEYED_SUPER_PROPERTY: { |
2187 old_value = register_allocator()->NewRegister(); | 2149 old_value = register_allocator()->NewRegister(); |
2188 BuildKeyedSuperPropertyLoad(&super_args); | 2150 BuildKeyedSuperPropertyLoad(object); |
2189 builder()->StoreAccumulatorInRegister(old_value); | 2151 builder()->StoreAccumulatorInRegister(old_value); |
2190 break; | 2152 break; |
2191 } | 2153 } |
2192 } | 2154 } |
2193 VisitForAccumulatorValue(expr->value()); | 2155 VisitForAccumulatorValue(expr->value()); |
2194 builder()->BinaryOperation(expr->binary_op(), old_value); | 2156 builder()->BinaryOperation(expr->binary_op(), old_value); |
2195 } else { | 2157 } else { |
2196 VisitForAccumulatorValue(expr->value()); | 2158 VisitForAccumulatorValue(expr->value()); |
2197 } | 2159 } |
2198 | 2160 |
2199 // Store the value. | 2161 // Store the value. |
2200 FeedbackVectorSlot slot = expr->AssignmentSlot(); | 2162 FeedbackVectorSlot slot = expr->AssignmentSlot(); |
2201 switch (assign_type) { | 2163 switch (assign_type) { |
2202 case VARIABLE: { | 2164 case VARIABLE: { |
2203 // TODO(oth): The VisitVariableAssignment() call is hard to reason about. | 2165 // TODO(oth): The VisitVariableAssignment() call is hard to reason about. |
2204 // Is the value in the accumulator safe? Yes, but scary. | 2166 // Is the value in the accumulator safe? Yes, but scary. |
2205 Variable* variable = expr->target()->AsVariableProxy()->var(); | 2167 Variable* variable = expr->target()->AsVariableProxy()->var(); |
2206 VisitVariableAssignment(variable, expr->op(), slot); | 2168 VisitVariableAssignment(variable, expr->op(), slot); |
2207 break; | 2169 break; |
2208 } | 2170 } |
2209 case NAMED_PROPERTY: | 2171 case NAMED_PROPERTY: |
2210 builder()->StoreNamedProperty(object, name, feedback_index(slot), | 2172 builder()->StoreNamedProperty(object, name, feedback_index(slot), |
2211 language_mode()); | 2173 language_mode()); |
2212 break; | 2174 break; |
2213 case KEYED_PROPERTY: | 2175 case KEYED_PROPERTY: |
2214 builder()->StoreKeyedProperty(object, key, feedback_index(slot), | 2176 builder()->StoreKeyedProperty(object, key, feedback_index(slot), |
2215 language_mode()); | 2177 language_mode()); |
2216 break; | 2178 break; |
2217 case NAMED_SUPER_PROPERTY: { | 2179 case NAMED_SUPER_PROPERTY: { |
2218 BuildNamedSuperPropertyStore(&super_args); | 2180 builder()->StoreAccumulatorInRegister(value); |
2181 BuildNamedSuperPropertyStore(object); | |
2219 break; | 2182 break; |
2220 } | 2183 } |
2221 case KEYED_SUPER_PROPERTY: { | 2184 case KEYED_SUPER_PROPERTY: { |
2222 BuildKeyedSuperPropertyStore(&super_args); | 2185 builder()->StoreAccumulatorInRegister(value); |
2186 BuildKeyedSuperPropertyStore(object); | |
2223 break; | 2187 break; |
2224 } | 2188 } |
2225 } | 2189 } |
2226 execution_result()->SetResultInAccumulator(); | 2190 execution_result()->SetResultInAccumulator(); |
2227 } | 2191 } |
2228 | 2192 |
2229 | 2193 |
2230 void BytecodeGenerator::VisitYield(Yield* expr) { UNIMPLEMENTED(); } | 2194 void BytecodeGenerator::VisitYield(Yield* expr) { UNIMPLEMENTED(); } |
2231 | 2195 |
2232 | 2196 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2270 | 2234 |
2271 void BytecodeGenerator::VisitPropertyLoadForAccumulator(Register obj, | 2235 void BytecodeGenerator::VisitPropertyLoadForAccumulator(Register obj, |
2272 Property* expr) { | 2236 Property* expr) { |
2273 AccumulatorResultScope result_scope(this); | 2237 AccumulatorResultScope result_scope(this); |
2274 VisitPropertyLoad(obj, expr); | 2238 VisitPropertyLoad(obj, expr); |
2275 } | 2239 } |
2276 | 2240 |
2277 void BytecodeGenerator::VisitNamedSuperPropertyLoad(Property* property, | 2241 void BytecodeGenerator::VisitNamedSuperPropertyLoad(Property* property, |
2278 Register opt_receiver_out) { | 2242 Register opt_receiver_out) { |
2279 RegisterAllocationScope register_scope(this); | 2243 RegisterAllocationScope register_scope(this); |
2280 SuperPropertyArguments super_args; | 2244 register_allocator()->PrepareForConsecutiveAllocations(3); |
2281 PrepareNamedSuperPropertyArguments( | 2245 |
2282 property->obj()->AsSuperPropertyReference(), | 2246 Register receiver, home_object, name; |
2283 property->key()->AsLiteral()->AsPropertyName(), &super_args); | 2247 receiver = register_allocator()->NextConsecutiveRegister(); |
2248 home_object = register_allocator()->NextConsecutiveRegister(); | |
2249 name = register_allocator()->NextConsecutiveRegister(); | |
2250 SuperPropertyReference* super_property = | |
2251 property->obj()->AsSuperPropertyReference(); | |
2252 VisitForRegisterValue(super_property->this_var(), receiver); | |
2253 VisitForRegisterValue(super_property->home_object(), home_object); | |
2254 builder() | |
2255 ->LoadLiteral(property->key()->AsLiteral()->AsPropertyName()) | |
2256 .StoreAccumulatorInRegister(name); | |
2257 BuildNamedSuperPropertyLoad(receiver); | |
2284 if (opt_receiver_out.is_valid()) { | 2258 if (opt_receiver_out.is_valid()) { |
2285 builder()->MoveRegister(super_args.receiver(), opt_receiver_out); | 2259 builder()->MoveRegister(receiver, opt_receiver_out); |
2286 } | 2260 } |
2287 BuildNamedSuperPropertyLoad(&super_args); | |
2288 } | 2261 } |
2289 | 2262 |
2290 void BytecodeGenerator::VisitKeyedSuperPropertyLoad(Property* property, | 2263 void BytecodeGenerator::VisitKeyedSuperPropertyLoad(Property* property, |
2291 Register opt_receiver_out) { | 2264 Register opt_receiver_out) { |
2292 RegisterAllocationScope register_scope(this); | 2265 RegisterAllocationScope register_scope(this); |
2293 SuperPropertyArguments super_args; | 2266 Register receiver, home_object, key; |
2294 PrepareKeyedSuperPropertyArguments( | 2267 register_allocator()->PrepareForConsecutiveAllocations(3); |
2295 property->obj()->AsSuperPropertyReference(), property->key(), | 2268 receiver = register_allocator()->NextConsecutiveRegister(); |
2296 &super_args); | 2269 home_object = register_allocator()->NextConsecutiveRegister(); |
2270 key = register_allocator()->NextConsecutiveRegister(); | |
2271 SuperPropertyReference* super_property = | |
2272 property->obj()->AsSuperPropertyReference(); | |
2273 VisitForRegisterValue(super_property->this_var(), receiver); | |
2274 VisitForRegisterValue(super_property->home_object(), home_object); | |
2275 VisitForRegisterValue(property->key(), key); | |
2276 BuildKeyedSuperPropertyLoad(receiver); | |
2277 | |
2297 if (opt_receiver_out.is_valid()) { | 2278 if (opt_receiver_out.is_valid()) { |
2298 builder()->MoveRegister(super_args.receiver(), opt_receiver_out); | 2279 builder()->MoveRegister(receiver, opt_receiver_out); |
2299 } | 2280 } |
2300 BuildKeyedSuperPropertyLoad(&super_args); | |
2301 } | 2281 } |
2302 | 2282 |
2303 void BytecodeGenerator::VisitProperty(Property* expr) { | 2283 void BytecodeGenerator::VisitProperty(Property* expr) { |
2304 LhsKind property_kind = Property::GetAssignType(expr); | 2284 LhsKind property_kind = Property::GetAssignType(expr); |
2305 if (property_kind != NAMED_SUPER_PROPERTY && | 2285 if (property_kind != NAMED_SUPER_PROPERTY && |
2306 property_kind != KEYED_SUPER_PROPERTY) { | 2286 property_kind != KEYED_SUPER_PROPERTY) { |
2307 Register obj = VisitForRegisterValue(expr->obj()); | 2287 Register obj = VisitForRegisterValue(expr->obj()); |
2308 VisitPropertyLoad(obj, expr); | 2288 VisitPropertyLoad(obj, expr); |
2309 } else { | 2289 } else { |
2310 VisitPropertyLoad(Register::invalid_value(), expr); | 2290 VisitPropertyLoad(Register::invalid_value(), expr); |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2654 DCHECK(expr->expression()->IsValidReferenceExpressionOrThis()); | 2634 DCHECK(expr->expression()->IsValidReferenceExpressionOrThis()); |
2655 | 2635 |
2656 // Left-hand side can only be a property, a global or a variable slot. | 2636 // Left-hand side can only be a property, a global or a variable slot. |
2657 Property* property = expr->expression()->AsProperty(); | 2637 Property* property = expr->expression()->AsProperty(); |
2658 LhsKind assign_type = Property::GetAssignType(property); | 2638 LhsKind assign_type = Property::GetAssignType(property); |
2659 | 2639 |
2660 // TODO(rmcilroy): Set is_postfix to false if visiting for effect. | 2640 // TODO(rmcilroy): Set is_postfix to false if visiting for effect. |
2661 bool is_postfix = expr->is_postfix(); | 2641 bool is_postfix = expr->is_postfix(); |
2662 | 2642 |
2663 // Evaluate LHS expression and get old value. | 2643 // Evaluate LHS expression and get old value. |
2664 Register object, key, old_value; | 2644 Register object, home_object, key, old_value, value; |
2665 SuperPropertyArguments super_args; | |
2666 Handle<String> name; | 2645 Handle<String> name; |
2667 switch (assign_type) { | 2646 switch (assign_type) { |
2668 case VARIABLE: { | 2647 case VARIABLE: { |
2669 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 2648 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
2670 VisitVariableLoadForAccumulatorValue(proxy->var(), | 2649 VisitVariableLoadForAccumulatorValue(proxy->var(), |
2671 proxy->VariableFeedbackSlot()); | 2650 proxy->VariableFeedbackSlot()); |
2672 break; | 2651 break; |
2673 } | 2652 } |
2674 case NAMED_PROPERTY: { | 2653 case NAMED_PROPERTY: { |
2675 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); | 2654 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); |
2676 object = VisitForRegisterValue(property->obj()); | 2655 object = VisitForRegisterValue(property->obj()); |
2677 name = property->key()->AsLiteral()->AsPropertyName(); | 2656 name = property->key()->AsLiteral()->AsPropertyName(); |
2678 builder()->LoadNamedProperty(object, name, feedback_index(slot)); | 2657 builder()->LoadNamedProperty(object, name, feedback_index(slot)); |
2679 break; | 2658 break; |
2680 } | 2659 } |
2681 case KEYED_PROPERTY: { | 2660 case KEYED_PROPERTY: { |
2682 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); | 2661 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); |
2683 object = VisitForRegisterValue(property->obj()); | 2662 object = VisitForRegisterValue(property->obj()); |
2684 // Use visit for accumulator here since we need the key in the accumulator | 2663 // Use visit for accumulator here since we need the key in the accumulator |
2685 // for the LoadKeyedProperty. | 2664 // for the LoadKeyedProperty. |
2686 key = register_allocator()->NewRegister(); | 2665 key = register_allocator()->NewRegister(); |
2687 VisitForAccumulatorValue(property->key()); | 2666 VisitForAccumulatorValue(property->key()); |
2688 builder()->StoreAccumulatorInRegister(key).LoadKeyedProperty( | 2667 builder()->StoreAccumulatorInRegister(key).LoadKeyedProperty( |
2689 object, feedback_index(slot)); | 2668 object, feedback_index(slot)); |
2690 break; | 2669 break; |
2691 } | 2670 } |
2692 case NAMED_SUPER_PROPERTY: { | 2671 case NAMED_SUPER_PROPERTY: { |
2693 PrepareNamedSuperPropertyArguments( | 2672 register_allocator()->PrepareForConsecutiveAllocations(4); |
2694 property->obj()->AsSuperPropertyReference(), | 2673 object = register_allocator()->NextConsecutiveRegister(); |
2695 property->key()->AsLiteral()->AsPropertyName(), &super_args); | 2674 home_object = register_allocator()->NextConsecutiveRegister(); |
2696 BuildNamedSuperPropertyLoad(&super_args); | 2675 key = register_allocator()->NextConsecutiveRegister(); |
2676 value = register_allocator()->NextConsecutiveRegister(); | |
2677 SuperPropertyReference* super_property = | |
2678 property->obj()->AsSuperPropertyReference(); | |
2679 VisitForRegisterValue(super_property->this_var(), object); | |
2680 VisitForRegisterValue(super_property->home_object(), home_object); | |
2681 builder() | |
2682 ->LoadLiteral(property->key()->AsLiteral()->AsPropertyName()) | |
2683 .StoreAccumulatorInRegister(key); | |
2684 BuildNamedSuperPropertyLoad(object); | |
2697 break; | 2685 break; |
2698 } | 2686 } |
2699 case KEYED_SUPER_PROPERTY: { | 2687 case KEYED_SUPER_PROPERTY: { |
2700 PrepareKeyedSuperPropertyArguments( | 2688 register_allocator()->PrepareForConsecutiveAllocations(4); |
2701 property->obj()->AsSuperPropertyReference(), property->key(), | 2689 object = register_allocator()->NextConsecutiveRegister(); |
2702 &super_args); | 2690 home_object = register_allocator()->NextConsecutiveRegister(); |
2703 BuildKeyedSuperPropertyLoad(&super_args); | 2691 key = register_allocator()->NextConsecutiveRegister(); |
2692 value = register_allocator()->NextConsecutiveRegister(); | |
2693 builder()->StoreAccumulatorInRegister(value); | |
2694 SuperPropertyReference* super_property = | |
2695 property->obj()->AsSuperPropertyReference(); | |
2696 VisitForRegisterValue(super_property->this_var(), object); | |
2697 VisitForRegisterValue(super_property->home_object(), home_object); | |
2698 VisitForRegisterValue(property->key(), key); | |
2699 BuildKeyedSuperPropertyLoad(object); | |
2704 break; | 2700 break; |
2705 } | 2701 } |
2706 } | 2702 } |
2707 | 2703 |
2708 // Convert old value into a number. | 2704 // Convert old value into a number. |
2709 if (!is_strong(language_mode())) { | 2705 if (!is_strong(language_mode())) { |
2710 builder()->CastAccumulatorToNumber(); | 2706 builder()->CastAccumulatorToNumber(); |
2711 } | 2707 } |
2712 | 2708 |
2713 // Save result for postfix expressions. | 2709 // Save result for postfix expressions. |
(...skipping 17 matching lines...) Expand all Loading... | |
2731 builder()->StoreNamedProperty(object, name, feedback_index(feedback_slot), | 2727 builder()->StoreNamedProperty(object, name, feedback_index(feedback_slot), |
2732 language_mode()); | 2728 language_mode()); |
2733 break; | 2729 break; |
2734 } | 2730 } |
2735 case KEYED_PROPERTY: { | 2731 case KEYED_PROPERTY: { |
2736 builder()->StoreKeyedProperty(object, key, feedback_index(feedback_slot), | 2732 builder()->StoreKeyedProperty(object, key, feedback_index(feedback_slot), |
2737 language_mode()); | 2733 language_mode()); |
2738 break; | 2734 break; |
2739 } | 2735 } |
2740 case NAMED_SUPER_PROPERTY: { | 2736 case NAMED_SUPER_PROPERTY: { |
2741 BuildNamedSuperPropertyStore(&super_args); | 2737 builder()->StoreAccumulatorInRegister(value); |
2738 BuildNamedSuperPropertyStore(object); | |
2742 break; | 2739 break; |
2743 } | 2740 } |
2744 case KEYED_SUPER_PROPERTY: { | 2741 case KEYED_SUPER_PROPERTY: { |
2745 BuildKeyedSuperPropertyStore(&super_args); | 2742 builder()->StoreAccumulatorInRegister(value); |
2743 BuildKeyedSuperPropertyStore(object); | |
2746 break; | 2744 break; |
2747 } | 2745 } |
2748 } | 2746 } |
2749 | 2747 |
2750 // Restore old value for postfix expressions. | 2748 // Restore old value for postfix expressions. |
2751 if (is_postfix) { | 2749 if (is_postfix) { |
2752 execution_result()->SetResultInRegister(old_value); | 2750 execution_result()->SetResultInRegister(old_value); |
2753 } else { | 2751 } else { |
2754 execution_result()->SetResultInAccumulator(); | 2752 execution_result()->SetResultInAccumulator(); |
2755 } | 2753 } |
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3091 | 3089 |
3092 | 3090 |
3093 // Visits the expression |expr| and returns the register containing | 3091 // Visits the expression |expr| and returns the register containing |
3094 // the expression result. | 3092 // the expression result. |
3095 Register BytecodeGenerator::VisitForRegisterValue(Expression* expr) { | 3093 Register BytecodeGenerator::VisitForRegisterValue(Expression* expr) { |
3096 RegisterResultScope register_scope(this); | 3094 RegisterResultScope register_scope(this); |
3097 Visit(expr); | 3095 Visit(expr); |
3098 return register_scope.ResultRegister(); | 3096 return register_scope.ResultRegister(); |
3099 } | 3097 } |
3100 | 3098 |
3099 // Visits the expression |expr| and stores the expression result in | |
3100 // |destination|. | |
3101 void BytecodeGenerator::VisitForRegisterValue(Expression* expr, | |
3102 Register destination) { | |
3103 AccumulatorResultScope register_scope(this); | |
3104 Visit(expr); | |
3105 builder()->StoreAccumulatorInRegister(destination); | |
3106 } | |
3101 | 3107 |
3102 void BytecodeGenerator::VisitInScope(Statement* stmt, Scope* scope) { | 3108 void BytecodeGenerator::VisitInScope(Statement* stmt, Scope* scope) { |
3103 ContextScope context_scope(this, scope); | 3109 ContextScope context_scope(this, scope); |
3104 DCHECK(scope->declarations()->is_empty()); | 3110 DCHECK(scope->declarations()->is_empty()); |
3105 Visit(stmt); | 3111 Visit(stmt); |
3106 } | 3112 } |
3107 | 3113 |
3108 | 3114 |
3109 LanguageMode BytecodeGenerator::language_mode() const { | 3115 LanguageMode BytecodeGenerator::language_mode() const { |
3110 return info()->language_mode(); | 3116 return info()->language_mode(); |
3111 } | 3117 } |
3112 | 3118 |
3113 | 3119 |
3114 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 3120 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
3115 return info()->feedback_vector()->GetIndex(slot); | 3121 return info()->feedback_vector()->GetIndex(slot); |
3116 } | 3122 } |
3117 | 3123 |
3118 } // namespace interpreter | 3124 } // namespace interpreter |
3119 } // namespace internal | 3125 } // namespace internal |
3120 } // namespace v8 | 3126 } // namespace v8 |
OLD | NEW |