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 1032 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1043 RegisterAllocationScope register_scope(this); | 1043 RegisterAllocationScope register_scope(this); |
1044 Register value = register_allocator()->NewRegister(); | 1044 Register value = register_allocator()->NewRegister(); |
1045 builder()->StoreAccumulatorInRegister(value); | 1045 builder()->StoreAccumulatorInRegister(value); |
1046 Register object = VisitForRegisterValue(property->obj()); | 1046 Register object = VisitForRegisterValue(property->obj()); |
1047 Register key = VisitForRegisterValue(property->key()); | 1047 Register key = VisitForRegisterValue(property->key()); |
1048 builder()->LoadAccumulatorWithRegister(value); | 1048 builder()->LoadAccumulatorWithRegister(value); |
1049 builder()->StoreKeyedProperty(object, key, feedback_index(slot), | 1049 builder()->StoreKeyedProperty(object, key, feedback_index(slot), |
1050 language_mode()); | 1050 language_mode()); |
1051 break; | 1051 break; |
1052 } | 1052 } |
1053 case NAMED_SUPER_PROPERTY: | 1053 case NAMED_SUPER_PROPERTY: { |
1054 case KEYED_SUPER_PROPERTY: | 1054 RegisterAllocationScope register_scope(this); |
1055 UNIMPLEMENTED(); | 1055 Register value = register_allocator()->NewRegister(); |
1056 builder()->StoreAccumulatorInRegister(value); | |
1057 Register receiver = PrepareNamedSuperPropertyArguments( | |
1058 property->obj()->AsSuperPropertyReference(), | |
1059 property->key()->AsLiteral()->AsPropertyName()); | |
1060 builder()->LoadAccumulatorWithRegister(value); | |
1061 BuildNamedSuperPropertyStore(receiver); | |
1062 break; | |
1063 } | |
1064 case KEYED_SUPER_PROPERTY: { | |
1065 RegisterAllocationScope register_scope(this); | |
1066 Register value = register_allocator()->NewRegister(); | |
1067 builder()->StoreAccumulatorInRegister(value); | |
1068 Register receiver = PrepareKeyedSuperPropertyArguments( | |
1069 property->obj()->AsSuperPropertyReference(), property->key()); | |
1070 builder()->LoadAccumulatorWithRegister(value); | |
1071 BuildKeyedSuperPropertyStore(receiver); | |
1072 break; | |
1073 } | |
1056 } | 1074 } |
1057 } | 1075 } |
1058 | 1076 |
1059 | 1077 |
1060 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) { | 1078 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) { |
1061 if (stmt->subject()->IsNullLiteral() || | 1079 if (stmt->subject()->IsNullLiteral() || |
1062 stmt->subject()->IsUndefinedLiteral(isolate())) { | 1080 stmt->subject()->IsUndefinedLiteral(isolate())) { |
1063 // ForIn generates lots of code, skip if it wouldn't produce any effects. | 1081 // ForIn generates lots of code, skip if it wouldn't produce any effects. |
1064 return; | 1082 return; |
1065 } | 1083 } |
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1488 UNREACHABLE(); | 1506 UNREACHABLE(); |
1489 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1507 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
1490 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1508 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); |
1491 // Fall through. | 1509 // Fall through. |
1492 case ObjectLiteral::Property::COMPUTED: { | 1510 case ObjectLiteral::Property::COMPUTED: { |
1493 // It is safe to use [[Put]] here because the boilerplate already | 1511 // It is safe to use [[Put]] here because the boilerplate already |
1494 // contains computed properties with an uninitialized value. | 1512 // contains computed properties with an uninitialized value. |
1495 if (literal_key->value()->IsInternalizedString()) { | 1513 if (literal_key->value()->IsInternalizedString()) { |
1496 if (property->emit_store()) { | 1514 if (property->emit_store()) { |
1497 VisitForAccumulatorValue(property->value()); | 1515 VisitForAccumulatorValue(property->value()); |
1498 builder()->StoreNamedProperty( | 1516 if (FunctionLiteral::NeedsHomeObject(property->value())) { |
1499 literal, literal_key->AsPropertyName(), | 1517 RegisterAllocationScope register_scope(this); |
1500 feedback_index(property->GetSlot(0)), language_mode()); | 1518 Register value = register_allocator()->NewRegister(); |
1519 builder()->StoreAccumulatorInRegister(value); | |
1520 builder()->StoreNamedProperty( | |
1521 literal, literal_key->AsPropertyName(), | |
1522 feedback_index(property->GetSlot(0)), language_mode()); | |
1523 VisitSetHomeObject(value, literal, property, 1); | |
1524 } else { | |
1525 builder()->StoreNamedProperty( | |
1526 literal, literal_key->AsPropertyName(), | |
1527 feedback_index(property->GetSlot(0)), language_mode()); | |
1528 } | |
1501 } else { | 1529 } else { |
1502 VisitForEffect(property->value()); | 1530 VisitForEffect(property->value()); |
1503 } | 1531 } |
1504 } else { | 1532 } else { |
1505 register_allocator()->PrepareForConsecutiveAllocations(4); | 1533 register_allocator()->PrepareForConsecutiveAllocations(4); |
1506 Register literal_argument = | 1534 Register literal_argument = |
1507 register_allocator()->NextConsecutiveRegister(); | 1535 register_allocator()->NextConsecutiveRegister(); |
1508 Register key = register_allocator()->NextConsecutiveRegister(); | 1536 Register key = register_allocator()->NextConsecutiveRegister(); |
1509 Register value = register_allocator()->NextConsecutiveRegister(); | 1537 Register value = register_allocator()->NextConsecutiveRegister(); |
1510 Register language = register_allocator()->NextConsecutiveRegister(); | 1538 Register language = register_allocator()->NextConsecutiveRegister(); |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1778 } | 1806 } |
1779 | 1807 |
1780 | 1808 |
1781 Register BytecodeGenerator::VisitVariableLoadForRegisterValue( | 1809 Register BytecodeGenerator::VisitVariableLoadForRegisterValue( |
1782 Variable* variable, FeedbackVectorSlot slot, TypeofMode typeof_mode) { | 1810 Variable* variable, FeedbackVectorSlot slot, TypeofMode typeof_mode) { |
1783 RegisterResultScope register_scope(this); | 1811 RegisterResultScope register_scope(this); |
1784 VisitVariableLoad(variable, slot, typeof_mode); | 1812 VisitVariableLoad(variable, slot, typeof_mode); |
1785 return register_scope.ResultRegister(); | 1813 return register_scope.ResultRegister(); |
1786 } | 1814 } |
1787 | 1815 |
1816 template <size_t N> | |
1817 void BytecodeGenerator::InitializeWithConsecutiveRegisters( | |
1818 Register (®isters)[N]) { | |
1819 register_allocator()->PrepareForConsecutiveAllocations(N); | |
1820 for (size_t i = 0; i < N; i++) { | |
1821 registers[i] = register_allocator()->NextConsecutiveRegister(); | |
1822 } | |
1823 } | |
1824 | |
1825 Register BytecodeGenerator::PrepareNamedSuperPropertyArguments( | |
1826 SuperPropertyReference* super_property, Handle<Name> name) { | |
1827 Register args[4]; | |
1828 register_allocator()->PrepareForConsecutiveAllocations(arraysize(args)); | |
rmcilroy
2016/02/12 14:56:42
unecessary, right? (InitializeWithConsecutiveRegis
oth
2016/02/12 16:50:33
Done.
| |
1829 | |
1830 InitializeWithConsecutiveRegisters(args); | |
rmcilroy
2016/02/12 14:56:42
nit - move below Register args[4]; and add whitesp
oth
2016/02/12 16:50:33
Done.
| |
1831 VisitForAccumulatorValue(super_property->this_var()); | |
1832 builder()->StoreAccumulatorInRegister(args[0]); | |
1833 VisitForAccumulatorValue(super_property->home_object()); | |
1834 builder()->StoreAccumulatorInRegister(args[1]); | |
1835 builder() | |
1836 ->LoadLiteral(name) | |
1837 .StoreAccumulatorInRegister(args[2]) | |
1838 .LoadLiteral(Smi::FromInt(static_cast<int>(language_mode()))) | |
1839 .StoreAccumulatorInRegister(args[3]); | |
rmcilroy
2016/02/12 14:56:42
As discussed, please drop storing language mode he
oth
2016/02/12 16:50:33
Done.
| |
1840 return args[0]; | |
1841 } | |
1842 | |
1843 Register BytecodeGenerator::PrepareKeyedSuperPropertyArguments( | |
1844 SuperPropertyReference* super_property, Expression* key) { | |
1845 Register args[4]; | |
1846 register_allocator()->PrepareForConsecutiveAllocations(arraysize(args)); | |
rmcilroy
2016/02/12 14:56:42
ditto
oth
2016/02/12 16:50:33
Done.
| |
1847 | |
1848 InitializeWithConsecutiveRegisters(args); | |
rmcilroy
2016/02/12 14:56:42
ditto
oth
2016/02/12 16:50:33
Done.
| |
1849 VisitForAccumulatorValue(super_property->this_var()); | |
1850 builder()->StoreAccumulatorInRegister(args[0]); | |
1851 VisitForAccumulatorValue(super_property->home_object()); | |
1852 builder()->StoreAccumulatorInRegister(args[1]); | |
1853 VisitForAccumulatorValue(key); | |
1854 builder()->StoreAccumulatorInRegister(args[2]); | |
1855 // For load operations args[3] is the language mode, for stores | |
1856 // it is the value. | |
1857 return args[0]; | |
1858 } | |
1859 | |
1860 void BytecodeGenerator::BuildNamedSuperPropertyLoad(Register receiver) { | |
1861 Register mode(receiver.index() + 3); | |
1862 builder() | |
1863 ->LoadLiteral(Smi::FromInt(static_cast<int>(language_mode()))) | |
1864 .StoreAccumulatorInRegister(mode); | |
1865 builder()->CallRuntime(Runtime::kLoadFromSuper, receiver, 4); | |
1866 } | |
1867 | |
1868 void BytecodeGenerator::BuildKeyedSuperPropertyLoad(Register receiver) { | |
1869 Register mode(receiver.index() + 3); | |
1870 builder() | |
1871 ->LoadLiteral(Smi::FromInt(static_cast<int>(language_mode()))) | |
1872 .StoreAccumulatorInRegister(mode); | |
1873 builder()->CallRuntime(Runtime::kLoadKeyedFromSuper, receiver, 4); | |
1874 } | |
1875 | |
1876 void BytecodeGenerator::BuildNamedSuperPropertyStore(Register receiver) { | |
1877 Register value(receiver.index() + 3); | |
1878 builder()->StoreAccumulatorInRegister(value); | |
1879 Runtime::FunctionId function_id = is_strict(language_mode()) | |
1880 ? Runtime::kStoreToSuper_Strict | |
1881 : Runtime::kStoreToSuper_Sloppy; | |
1882 builder()->CallRuntime(function_id, receiver, 4); | |
1883 } | |
1884 | |
1885 void BytecodeGenerator::BuildKeyedSuperPropertyStore(Register receiver) { | |
1886 Register value(receiver.index() + 3); | |
1887 builder()->StoreAccumulatorInRegister(value); | |
1888 Runtime::FunctionId function_id = is_strict(language_mode()) | |
1889 ? Runtime::kStoreKeyedToSuper_Strict | |
1890 : Runtime::kStoreKeyedToSuper_Sloppy; | |
1891 builder()->CallRuntime(function_id, receiver, 4); | |
1892 } | |
1893 | |
1788 void BytecodeGenerator::BuildThrowIfHole(Handle<String> name) { | 1894 void BytecodeGenerator::BuildThrowIfHole(Handle<String> name) { |
1789 Register name_reg = register_allocator()->NewRegister(); | 1895 Register name_reg = register_allocator()->NewRegister(); |
1790 BytecodeLabel end_label; | 1896 BytecodeLabel end_label; |
1791 // TODO(mythria): This will be replaced by a new bytecode that throws an | 1897 // TODO(mythria): This will be replaced by a new bytecode that throws an |
1792 // error if the value is the hole. | 1898 // error if the value is the hole. |
1793 builder() | 1899 builder() |
1794 ->JumpIfNotHole(&end_label) | 1900 ->JumpIfNotHole(&end_label) |
1795 .LoadLiteral(name) | 1901 .LoadLiteral(name) |
1796 .StoreAccumulatorInRegister(name_reg) | 1902 .StoreAccumulatorInRegister(name_reg) |
1797 .CallRuntime(Runtime::kThrowReferenceError, name_reg, 1) | 1903 .CallRuntime(Runtime::kThrowReferenceError, name_reg, 1) |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1986 } else { | 2092 } else { |
1987 builder()->StoreLookupSlot(variable->name(), language_mode()); | 2093 builder()->StoreLookupSlot(variable->name(), language_mode()); |
1988 } | 2094 } |
1989 break; | 2095 break; |
1990 } | 2096 } |
1991 } | 2097 } |
1992 } | 2098 } |
1993 | 2099 |
1994 | 2100 |
1995 void BytecodeGenerator::VisitAssignment(Assignment* expr) { | 2101 void BytecodeGenerator::VisitAssignment(Assignment* expr) { |
1996 DCHECK(expr->target()->IsValidReferenceExpression()); | 2102 DCHECK(expr->target()->IsValidReferenceExpressionOrThis()); |
1997 Register object, key; | 2103 Register object, key; |
1998 Handle<String> name; | 2104 Handle<String> name; |
1999 | 2105 |
2000 // Left-hand side can only be a property, a global or a variable slot. | 2106 // Left-hand side can only be a property, a global or a variable slot. |
2001 Property* property = expr->target()->AsProperty(); | 2107 Property* property = expr->target()->AsProperty(); |
2002 LhsKind assign_type = Property::GetAssignType(property); | 2108 LhsKind assign_type = Property::GetAssignType(property); |
2003 | 2109 |
2004 // Evaluate LHS expression. | 2110 // Evaluate LHS expression. |
2005 switch (assign_type) { | 2111 switch (assign_type) { |
2006 case VARIABLE: | 2112 case VARIABLE: |
(...skipping 10 matching lines...) Expand all Loading... | |
2017 // Use VisitForAccumulator and store to register so that the key is | 2123 // Use VisitForAccumulator and store to register so that the key is |
2018 // still in the accumulator for loading the old value below. | 2124 // still in the accumulator for loading the old value below. |
2019 key = register_allocator()->NewRegister(); | 2125 key = register_allocator()->NewRegister(); |
2020 VisitForAccumulatorValue(property->key()); | 2126 VisitForAccumulatorValue(property->key()); |
2021 builder()->StoreAccumulatorInRegister(key); | 2127 builder()->StoreAccumulatorInRegister(key); |
2022 } else { | 2128 } else { |
2023 key = VisitForRegisterValue(property->key()); | 2129 key = VisitForRegisterValue(property->key()); |
2024 } | 2130 } |
2025 break; | 2131 break; |
2026 } | 2132 } |
2027 case NAMED_SUPER_PROPERTY: | 2133 case NAMED_SUPER_PROPERTY: { |
2028 case KEYED_SUPER_PROPERTY: | 2134 object = PrepareNamedSuperPropertyArguments( |
2029 UNIMPLEMENTED(); | 2135 property->obj()->AsSuperPropertyReference(), |
2136 property->key()->AsLiteral()->AsPropertyName()); | |
2137 break; | |
2138 } | |
2139 case KEYED_SUPER_PROPERTY: { | |
2140 object = PrepareKeyedSuperPropertyArguments( | |
2141 property->obj()->AsSuperPropertyReference(), property->key()); | |
2142 break; | |
2143 } | |
2030 } | 2144 } |
2031 | 2145 |
2032 // Evaluate the value and potentially handle compound assignments by loading | 2146 // Evaluate the value and potentially handle compound assignments by loading |
2033 // the left-hand side value and performing a binary operation. | 2147 // the left-hand side value and performing a binary operation. |
2034 if (expr->is_compound()) { | 2148 if (expr->is_compound()) { |
2035 Register old_value; | 2149 Register old_value; |
2036 switch (assign_type) { | 2150 switch (assign_type) { |
2037 case VARIABLE: { | 2151 case VARIABLE: { |
2038 VariableProxy* proxy = expr->target()->AsVariableProxy(); | 2152 VariableProxy* proxy = expr->target()->AsVariableProxy(); |
2039 old_value = VisitVariableLoadForRegisterValue( | 2153 old_value = VisitVariableLoadForRegisterValue( |
(...skipping 12 matching lines...) Expand all Loading... | |
2052 case KEYED_PROPERTY: { | 2166 case KEYED_PROPERTY: { |
2053 // Key is already in accumulator at this point due to evaluating the | 2167 // Key is already in accumulator at this point due to evaluating the |
2054 // LHS above. | 2168 // LHS above. |
2055 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); | 2169 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); |
2056 old_value = register_allocator()->NewRegister(); | 2170 old_value = register_allocator()->NewRegister(); |
2057 builder() | 2171 builder() |
2058 ->LoadKeyedProperty(object, feedback_index(slot), language_mode()) | 2172 ->LoadKeyedProperty(object, feedback_index(slot), language_mode()) |
2059 .StoreAccumulatorInRegister(old_value); | 2173 .StoreAccumulatorInRegister(old_value); |
2060 break; | 2174 break; |
2061 } | 2175 } |
2062 case NAMED_SUPER_PROPERTY: | 2176 case NAMED_SUPER_PROPERTY: { |
2063 case KEYED_SUPER_PROPERTY: | 2177 old_value = register_allocator()->NewRegister(); |
2064 UNIMPLEMENTED(); | 2178 BuildNamedSuperPropertyLoad(object); |
2179 builder()->StoreAccumulatorInRegister(old_value); | |
2065 break; | 2180 break; |
2181 } | |
2182 case KEYED_SUPER_PROPERTY: { | |
2183 old_value = register_allocator()->NewRegister(); | |
2184 BuildKeyedSuperPropertyLoad(object); | |
2185 builder()->StoreAccumulatorInRegister(old_value); | |
2186 break; | |
2187 } | |
2066 } | 2188 } |
2067 VisitForAccumulatorValue(expr->value()); | 2189 VisitForAccumulatorValue(expr->value()); |
2068 builder()->BinaryOperation(expr->binary_op(), old_value, | 2190 builder()->BinaryOperation(expr->binary_op(), old_value, |
2069 language_mode_strength()); | 2191 language_mode_strength()); |
2070 } else { | 2192 } else { |
2071 VisitForAccumulatorValue(expr->value()); | 2193 VisitForAccumulatorValue(expr->value()); |
2072 } | 2194 } |
2073 | 2195 |
2074 // Store the value. | 2196 // Store the value. |
2075 FeedbackVectorSlot slot = expr->AssignmentSlot(); | 2197 FeedbackVectorSlot slot = expr->AssignmentSlot(); |
2076 switch (assign_type) { | 2198 switch (assign_type) { |
2077 case VARIABLE: { | 2199 case VARIABLE: { |
2078 // TODO(oth): The VisitVariableAssignment() call is hard to reason about. | 2200 // TODO(oth): The VisitVariableAssignment() call is hard to reason about. |
2079 // Is the value in the accumulator safe? Yes, but scary. | 2201 // Is the value in the accumulator safe? Yes, but scary. |
2080 Variable* variable = expr->target()->AsVariableProxy()->var(); | 2202 Variable* variable = expr->target()->AsVariableProxy()->var(); |
2081 VisitVariableAssignment(variable, expr->op(), slot); | 2203 VisitVariableAssignment(variable, expr->op(), slot); |
2082 break; | 2204 break; |
2083 } | 2205 } |
2084 case NAMED_PROPERTY: | 2206 case NAMED_PROPERTY: |
2085 builder()->StoreNamedProperty(object, name, feedback_index(slot), | 2207 builder()->StoreNamedProperty(object, name, feedback_index(slot), |
2086 language_mode()); | 2208 language_mode()); |
2087 break; | 2209 break; |
2088 case KEYED_PROPERTY: | 2210 case KEYED_PROPERTY: |
2089 builder()->StoreKeyedProperty(object, key, feedback_index(slot), | 2211 builder()->StoreKeyedProperty(object, key, feedback_index(slot), |
2090 language_mode()); | 2212 language_mode()); |
2091 break; | 2213 break; |
2092 case NAMED_SUPER_PROPERTY: | 2214 case NAMED_SUPER_PROPERTY: { |
2093 case KEYED_SUPER_PROPERTY: | 2215 BuildNamedSuperPropertyStore(object); |
2094 UNIMPLEMENTED(); | 2216 break; |
2217 } | |
2218 case KEYED_SUPER_PROPERTY: { | |
2219 BuildKeyedSuperPropertyStore(object); | |
2220 break; | |
2221 } | |
2095 } | 2222 } |
2096 execution_result()->SetResultInAccumulator(); | 2223 execution_result()->SetResultInAccumulator(); |
2097 } | 2224 } |
2098 | 2225 |
2099 | 2226 |
2100 void BytecodeGenerator::VisitYield(Yield* expr) { UNIMPLEMENTED(); } | 2227 void BytecodeGenerator::VisitYield(Yield* expr) { UNIMPLEMENTED(); } |
2101 | 2228 |
2102 | 2229 |
2103 void BytecodeGenerator::VisitThrow(Throw* expr) { | 2230 void BytecodeGenerator::VisitThrow(Throw* expr) { |
2104 VisitForAccumulatorValue(expr->exception()); | 2231 VisitForAccumulatorValue(expr->exception()); |
(...skipping 17 matching lines...) Expand all Loading... | |
2122 expr->key()->AsLiteral()->AsPropertyName(), | 2249 expr->key()->AsLiteral()->AsPropertyName(), |
2123 feedback_index(slot), language_mode()); | 2250 feedback_index(slot), language_mode()); |
2124 break; | 2251 break; |
2125 } | 2252 } |
2126 case KEYED_PROPERTY: { | 2253 case KEYED_PROPERTY: { |
2127 VisitForAccumulatorValue(expr->key()); | 2254 VisitForAccumulatorValue(expr->key()); |
2128 builder()->LoadKeyedProperty(obj, feedback_index(slot), language_mode()); | 2255 builder()->LoadKeyedProperty(obj, feedback_index(slot), language_mode()); |
2129 break; | 2256 break; |
2130 } | 2257 } |
2131 case NAMED_SUPER_PROPERTY: | 2258 case NAMED_SUPER_PROPERTY: |
2259 VisitNamedSuperPropertyLoad(expr, Register::invalid_value()); | |
2260 break; | |
2132 case KEYED_SUPER_PROPERTY: | 2261 case KEYED_SUPER_PROPERTY: |
2133 UNIMPLEMENTED(); | 2262 VisitKeyedSuperPropertyLoad(expr, Register::invalid_value()); |
2263 break; | |
2134 } | 2264 } |
2135 execution_result()->SetResultInAccumulator(); | 2265 execution_result()->SetResultInAccumulator(); |
2136 } | 2266 } |
2137 | 2267 |
2138 | |
2139 void BytecodeGenerator::VisitPropertyLoadForAccumulator(Register obj, | 2268 void BytecodeGenerator::VisitPropertyLoadForAccumulator(Register obj, |
2140 Property* expr) { | 2269 Property* expr) { |
2141 AccumulatorResultScope result_scope(this); | 2270 AccumulatorResultScope result_scope(this); |
2142 VisitPropertyLoad(obj, expr); | 2271 VisitPropertyLoad(obj, expr); |
2143 } | 2272 } |
2144 | 2273 |
2274 void BytecodeGenerator::VisitNamedSuperPropertyLoad(Property* property, | |
2275 Register receiver_out) { | |
2276 RegisterAllocationScope register_scope(this); | |
2277 Register receiver = PrepareNamedSuperPropertyArguments( | |
2278 property->obj()->AsSuperPropertyReference(), | |
2279 property->key()->AsLiteral()->AsPropertyName()); | |
2280 if (receiver_out.is_valid()) { | |
2281 builder()->MoveRegister(receiver, receiver_out); | |
2282 } | |
2283 BuildNamedSuperPropertyLoad(receiver); | |
2284 } | |
2285 | |
2286 void BytecodeGenerator::VisitKeyedSuperPropertyLoad(Property* property, | |
2287 Register receiver_out) { | |
2288 RegisterAllocationScope register_scope(this); | |
2289 Register receiver = PrepareKeyedSuperPropertyArguments( | |
2290 property->obj()->AsSuperPropertyReference(), property->key()); | |
2291 if (receiver_out.is_valid()) { | |
2292 builder()->MoveRegister(receiver, receiver_out); | |
2293 } | |
2294 BuildKeyedSuperPropertyLoad(receiver); | |
2295 } | |
2145 | 2296 |
2146 void BytecodeGenerator::VisitProperty(Property* expr) { | 2297 void BytecodeGenerator::VisitProperty(Property* expr) { |
2147 Register obj = VisitForRegisterValue(expr->obj()); | 2298 LhsKind property_kind = Property::GetAssignType(expr); |
2148 VisitPropertyLoad(obj, expr); | 2299 if (property_kind != NAMED_SUPER_PROPERTY && |
2300 property_kind != KEYED_SUPER_PROPERTY) { | |
2301 Register obj = VisitForRegisterValue(expr->obj()); | |
2302 VisitPropertyLoad(obj, expr); | |
2303 } else { | |
2304 VisitPropertyLoad(Register::invalid_value(), expr); | |
2305 } | |
2149 } | 2306 } |
2150 | 2307 |
2151 | |
2152 Register BytecodeGenerator::VisitArguments(ZoneList<Expression*>* args) { | 2308 Register BytecodeGenerator::VisitArguments(ZoneList<Expression*>* args) { |
2153 if (args->length() == 0) { | 2309 if (args->length() == 0) { |
2154 return Register(); | 2310 return Register(); |
2155 } | 2311 } |
2156 | 2312 |
2157 // Visit arguments and place in a contiguous block of temporary | 2313 // Visit arguments and place in a contiguous block of temporary |
2158 // registers. Return the first temporary register corresponding to | 2314 // registers. Return the first temporary register corresponding to |
2159 // the first argument. | 2315 // the first argument. |
2160 // | 2316 // |
2161 // NB the caller may have already called | 2317 // NB the caller may have already called |
(...skipping 12 matching lines...) Expand all Loading... | |
2174 // Visit remaining arguments | 2330 // Visit remaining arguments |
2175 for (int i = 1; i < static_cast<int>(args->length()); i++) { | 2331 for (int i = 1; i < static_cast<int>(args->length()); i++) { |
2176 Register ith_arg = register_allocator()->NextConsecutiveRegister(); | 2332 Register ith_arg = register_allocator()->NextConsecutiveRegister(); |
2177 VisitForAccumulatorValue(args->at(i)); | 2333 VisitForAccumulatorValue(args->at(i)); |
2178 builder()->StoreAccumulatorInRegister(ith_arg); | 2334 builder()->StoreAccumulatorInRegister(ith_arg); |
2179 DCHECK(ith_arg.index() - i == first_arg.index()); | 2335 DCHECK(ith_arg.index() - i == first_arg.index()); |
2180 } | 2336 } |
2181 return first_arg; | 2337 return first_arg; |
2182 } | 2338 } |
2183 | 2339 |
2184 | |
2185 void BytecodeGenerator::VisitCall(Call* expr) { | 2340 void BytecodeGenerator::VisitCall(Call* expr) { |
2186 Expression* callee_expr = expr->expression(); | 2341 Expression* callee_expr = expr->expression(); |
2187 Call::CallType call_type = expr->GetCallType(isolate()); | 2342 Call::CallType call_type = expr->GetCallType(isolate()); |
2188 | 2343 |
2344 if (call_type == Call::SUPER_CALL) { | |
2345 return VisitCallSuper(expr); | |
2346 } | |
2347 | |
2189 // Prepare the callee and the receiver to the function call. This depends on | 2348 // Prepare the callee and the receiver to the function call. This depends on |
2190 // the semantics of the underlying call type. | 2349 // the semantics of the underlying call type. |
2191 | 2350 |
2192 // The receiver and arguments need to be allocated consecutively for | 2351 // The receiver and arguments need to be allocated consecutively for |
2193 // Call(). We allocate the callee and receiver consecutively for calls to | 2352 // Call(). We allocate the callee and receiver consecutively for calls to |
2194 // %LoadLookupSlotForCall. Future optimizations could avoid this there are | 2353 // %LoadLookupSlotForCall. Future optimizations could avoid this there are |
2195 // no arguments or the receiver and arguments are already consecutive. | 2354 // no arguments or the receiver and arguments are already consecutive. |
2196 ZoneList<Expression*>* args = expr->arguments(); | 2355 ZoneList<Expression*>* args = expr->arguments(); |
2197 register_allocator()->PrepareForConsecutiveAllocations(args->length() + 2); | 2356 register_allocator()->PrepareForConsecutiveAllocations(args->length() + 2); |
2198 Register callee = register_allocator()->NextConsecutiveRegister(); | 2357 Register callee = register_allocator()->NextConsecutiveRegister(); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2236 } | 2395 } |
2237 // Fall through. | 2396 // Fall through. |
2238 DCHECK_EQ(call_type, Call::POSSIBLY_EVAL_CALL); | 2397 DCHECK_EQ(call_type, Call::POSSIBLY_EVAL_CALL); |
2239 } | 2398 } |
2240 case Call::OTHER_CALL: { | 2399 case Call::OTHER_CALL: { |
2241 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); | 2400 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); |
2242 VisitForAccumulatorValue(callee_expr); | 2401 VisitForAccumulatorValue(callee_expr); |
2243 builder()->StoreAccumulatorInRegister(callee); | 2402 builder()->StoreAccumulatorInRegister(callee); |
2244 break; | 2403 break; |
2245 } | 2404 } |
2246 case Call::NAMED_SUPER_PROPERTY_CALL: | 2405 case Call::NAMED_SUPER_PROPERTY_CALL: { |
2247 case Call::KEYED_SUPER_PROPERTY_CALL: | 2406 Property* property = callee_expr->AsProperty(); |
2407 VisitNamedSuperPropertyLoad(property, receiver); | |
2408 builder()->StoreAccumulatorInRegister(callee); | |
2409 break; | |
2410 } | |
2411 case Call::KEYED_SUPER_PROPERTY_CALL: { | |
2412 Property* property = callee_expr->AsProperty(); | |
2413 VisitKeyedSuperPropertyLoad(property, receiver); | |
2414 builder()->StoreAccumulatorInRegister(callee); | |
2415 break; | |
2416 } | |
2248 case Call::SUPER_CALL: | 2417 case Call::SUPER_CALL: |
2249 UNIMPLEMENTED(); | 2418 UNREACHABLE(); |
2419 break; | |
2250 } | 2420 } |
2251 | 2421 |
2252 // Evaluate all arguments to the function call and store in sequential | 2422 // Evaluate all arguments to the function call and store in sequential |
2253 // registers. | 2423 // registers. |
2254 Register arg = VisitArguments(args); | 2424 Register arg = VisitArguments(args); |
2255 CHECK(args->length() == 0 || arg.index() == receiver.index() + 1); | 2425 CHECK(args->length() == 0 || arg.index() == receiver.index() + 1); |
2256 | 2426 |
2257 // Resolve callee for a potential direct eval call. This block will mutate the | 2427 // Resolve callee for a potential direct eval call. This block will mutate the |
2258 // callee value. | 2428 // callee value. |
2259 if (call_type == Call::POSSIBLY_EVAL_CALL && args->length() > 0) { | 2429 if (call_type == Call::POSSIBLY_EVAL_CALL && args->length() > 0) { |
(...skipping 23 matching lines...) Expand all Loading... | |
2283 ->CallRuntime(Runtime::kResolvePossiblyDirectEval, callee_for_eval, 5) | 2453 ->CallRuntime(Runtime::kResolvePossiblyDirectEval, callee_for_eval, 5) |
2284 .StoreAccumulatorInRegister(callee); | 2454 .StoreAccumulatorInRegister(callee); |
2285 } | 2455 } |
2286 | 2456 |
2287 builder()->SetExpressionPosition(expr); | 2457 builder()->SetExpressionPosition(expr); |
2288 builder()->Call(callee, receiver, 1 + args->length(), | 2458 builder()->Call(callee, receiver, 1 + args->length(), |
2289 feedback_index(expr->CallFeedbackICSlot())); | 2459 feedback_index(expr->CallFeedbackICSlot())); |
2290 execution_result()->SetResultInAccumulator(); | 2460 execution_result()->SetResultInAccumulator(); |
2291 } | 2461 } |
2292 | 2462 |
2463 void BytecodeGenerator::VisitCallSuper(Call* expr) { | |
2464 RegisterAllocationScope register_scope(this); | |
2465 SuperCallReference* super = expr->expression()->AsSuperCallReference(); | |
2466 | |
2467 // Prepare the constructor to the super call. | |
2468 Register this_function = register_allocator()->NewRegister(); | |
2469 VisitForAccumulatorValue(super->this_function_var()); | |
2470 builder() | |
2471 ->StoreAccumulatorInRegister(this_function) | |
2472 .CallRuntime(Runtime::kInlineGetSuperConstructor, this_function, 1); | |
2473 | |
2474 Register constructor = this_function; // Re-use dead this_function register. | |
2475 builder()->StoreAccumulatorInRegister(constructor); | |
2476 | |
2477 ZoneList<Expression*>* args = expr->arguments(); | |
2478 Register first_arg = VisitArguments(args); | |
2479 | |
2480 // The new target is loaded into the accumulator from the | |
2481 // {new.target} variable. | |
2482 VisitForAccumulatorValue(super->new_target_var()); | |
2483 | |
2484 // Call construct. | |
2485 builder()->SetExpressionPosition(expr); | |
2486 builder()->New(constructor, first_arg, args->length()); | |
2487 execution_result()->SetResultInAccumulator(); | |
2488 } | |
2293 | 2489 |
2294 void BytecodeGenerator::VisitCallNew(CallNew* expr) { | 2490 void BytecodeGenerator::VisitCallNew(CallNew* expr) { |
2295 Register constructor = register_allocator()->NewRegister(); | 2491 Register constructor = register_allocator()->NewRegister(); |
2296 VisitForAccumulatorValue(expr->expression()); | 2492 VisitForAccumulatorValue(expr->expression()); |
2297 builder()->StoreAccumulatorInRegister(constructor); | 2493 builder()->StoreAccumulatorInRegister(constructor); |
2298 | 2494 |
2299 ZoneList<Expression*>* args = expr->arguments(); | 2495 ZoneList<Expression*>* args = expr->arguments(); |
2300 Register first_arg = VisitArguments(args); | 2496 Register first_arg = VisitArguments(args); |
2497 | |
2301 builder()->SetExpressionPosition(expr); | 2498 builder()->SetExpressionPosition(expr); |
2302 builder()->New(constructor, first_arg, args->length()); | 2499 // The accumulator holds new target which is the same as the |
2500 // constructor for CallNew. | |
2501 builder() | |
2502 ->LoadAccumulatorWithRegister(constructor) | |
2503 .New(constructor, first_arg, args->length()); | |
2303 execution_result()->SetResultInAccumulator(); | 2504 execution_result()->SetResultInAccumulator(); |
2304 } | 2505 } |
2305 | 2506 |
2306 | 2507 |
2307 void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 2508 void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
2308 ZoneList<Expression*>* args = expr->arguments(); | 2509 ZoneList<Expression*>* args = expr->arguments(); |
2309 if (expr->is_jsruntime()) { | 2510 if (expr->is_jsruntime()) { |
2310 // Allocate a register for the receiver and load it with undefined. | 2511 // Allocate a register for the receiver and load it with undefined. |
2311 register_allocator()->PrepareForConsecutiveAllocations(1 + args->length()); | 2512 register_allocator()->PrepareForConsecutiveAllocations(1 + args->length()); |
2312 Register receiver = register_allocator()->NextConsecutiveRegister(); | 2513 Register receiver = register_allocator()->NextConsecutiveRegister(); |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2446 DCHECK(expr->expression()->IsValidReferenceExpressionOrThis()); | 2647 DCHECK(expr->expression()->IsValidReferenceExpressionOrThis()); |
2447 | 2648 |
2448 // Left-hand side can only be a property, a global or a variable slot. | 2649 // Left-hand side can only be a property, a global or a variable slot. |
2449 Property* property = expr->expression()->AsProperty(); | 2650 Property* property = expr->expression()->AsProperty(); |
2450 LhsKind assign_type = Property::GetAssignType(property); | 2651 LhsKind assign_type = Property::GetAssignType(property); |
2451 | 2652 |
2452 // TODO(rmcilroy): Set is_postfix to false if visiting for effect. | 2653 // TODO(rmcilroy): Set is_postfix to false if visiting for effect. |
2453 bool is_postfix = expr->is_postfix(); | 2654 bool is_postfix = expr->is_postfix(); |
2454 | 2655 |
2455 // Evaluate LHS expression and get old value. | 2656 // Evaluate LHS expression and get old value. |
2456 Register obj, key, old_value; | 2657 Register object, key, old_value; |
2457 Handle<String> name; | 2658 Handle<String> name; |
2458 switch (assign_type) { | 2659 switch (assign_type) { |
2459 case VARIABLE: { | 2660 case VARIABLE: { |
2460 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 2661 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
2461 VisitVariableLoadForAccumulatorValue(proxy->var(), | 2662 VisitVariableLoadForAccumulatorValue(proxy->var(), |
2462 proxy->VariableFeedbackSlot()); | 2663 proxy->VariableFeedbackSlot()); |
2463 break; | 2664 break; |
2464 } | 2665 } |
2465 case NAMED_PROPERTY: { | 2666 case NAMED_PROPERTY: { |
2466 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); | 2667 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); |
2467 obj = VisitForRegisterValue(property->obj()); | 2668 object = VisitForRegisterValue(property->obj()); |
2468 name = property->key()->AsLiteral()->AsPropertyName(); | 2669 name = property->key()->AsLiteral()->AsPropertyName(); |
2469 builder()->LoadNamedProperty(obj, name, feedback_index(slot), | 2670 builder()->LoadNamedProperty(object, name, feedback_index(slot), |
2470 language_mode()); | 2671 language_mode()); |
2471 break; | 2672 break; |
2472 } | 2673 } |
2473 case KEYED_PROPERTY: { | 2674 case KEYED_PROPERTY: { |
2474 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); | 2675 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); |
2475 obj = VisitForRegisterValue(property->obj()); | 2676 object = VisitForRegisterValue(property->obj()); |
2476 // Use visit for accumulator here since we need the key in the accumulator | 2677 // Use visit for accumulator here since we need the key in the accumulator |
2477 // for the LoadKeyedProperty. | 2678 // for the LoadKeyedProperty. |
2478 key = register_allocator()->NewRegister(); | 2679 key = register_allocator()->NewRegister(); |
2479 VisitForAccumulatorValue(property->key()); | 2680 VisitForAccumulatorValue(property->key()); |
2480 builder()->StoreAccumulatorInRegister(key).LoadKeyedProperty( | 2681 builder()->StoreAccumulatorInRegister(key).LoadKeyedProperty( |
2481 obj, feedback_index(slot), language_mode()); | 2682 object, feedback_index(slot), language_mode()); |
2482 break; | 2683 break; |
2483 } | 2684 } |
2484 case NAMED_SUPER_PROPERTY: | 2685 case NAMED_SUPER_PROPERTY: { |
2485 case KEYED_SUPER_PROPERTY: | 2686 object = PrepareNamedSuperPropertyArguments( |
2486 UNIMPLEMENTED(); | 2687 property->obj()->AsSuperPropertyReference(), |
2688 property->key()->AsLiteral()->AsPropertyName()); | |
2689 BuildNamedSuperPropertyLoad(object); | |
2690 break; | |
2691 } | |
2692 case KEYED_SUPER_PROPERTY: { | |
2693 object = PrepareKeyedSuperPropertyArguments( | |
2694 property->obj()->AsSuperPropertyReference(), property->key()); | |
2695 BuildKeyedSuperPropertyLoad(object); | |
2696 break; | |
2697 } | |
2487 } | 2698 } |
2488 | 2699 |
2489 // Convert old value into a number. | 2700 // Convert old value into a number. |
2490 if (!is_strong(language_mode())) { | 2701 if (!is_strong(language_mode())) { |
2491 builder()->CastAccumulatorToNumber(); | 2702 builder()->CastAccumulatorToNumber(); |
2492 } | 2703 } |
2493 | 2704 |
2494 // Save result for postfix expressions. | 2705 // Save result for postfix expressions. |
2495 if (is_postfix) { | 2706 if (is_postfix) { |
2496 old_value = register_allocator()->outer()->NewRegister(); | 2707 old_value = register_allocator()->outer()->NewRegister(); |
2497 builder()->StoreAccumulatorInRegister(old_value); | 2708 builder()->StoreAccumulatorInRegister(old_value); |
2498 } | 2709 } |
2499 | 2710 |
2500 // Perform +1/-1 operation. | 2711 // Perform +1/-1 operation. |
2501 builder()->CountOperation(expr->binary_op(), language_mode_strength()); | 2712 builder()->CountOperation(expr->binary_op(), language_mode_strength()); |
2502 | 2713 |
2503 // Store the value. | 2714 // Store the value. |
2504 FeedbackVectorSlot feedback_slot = expr->CountSlot(); | 2715 FeedbackVectorSlot feedback_slot = expr->CountSlot(); |
2505 switch (assign_type) { | 2716 switch (assign_type) { |
2506 case VARIABLE: { | 2717 case VARIABLE: { |
2507 Variable* variable = expr->expression()->AsVariableProxy()->var(); | 2718 Variable* variable = expr->expression()->AsVariableProxy()->var(); |
2508 VisitVariableAssignment(variable, expr->op(), feedback_slot); | 2719 VisitVariableAssignment(variable, expr->op(), feedback_slot); |
2509 break; | 2720 break; |
2510 } | 2721 } |
2511 case NAMED_PROPERTY: { | 2722 case NAMED_PROPERTY: { |
2512 builder()->StoreNamedProperty(obj, name, feedback_index(feedback_slot), | 2723 builder()->StoreNamedProperty(object, name, feedback_index(feedback_slot), |
2513 language_mode()); | 2724 language_mode()); |
2514 break; | 2725 break; |
2515 } | 2726 } |
2516 case KEYED_PROPERTY: { | 2727 case KEYED_PROPERTY: { |
2517 builder()->StoreKeyedProperty(obj, key, feedback_index(feedback_slot), | 2728 builder()->StoreKeyedProperty(object, key, feedback_index(feedback_slot), |
2518 language_mode()); | 2729 language_mode()); |
2519 break; | 2730 break; |
2520 } | 2731 } |
2521 case NAMED_SUPER_PROPERTY: | 2732 case NAMED_SUPER_PROPERTY: { |
2522 case KEYED_SUPER_PROPERTY: | 2733 BuildNamedSuperPropertyStore(object); |
2523 UNIMPLEMENTED(); | 2734 break; |
2735 } | |
2736 case KEYED_SUPER_PROPERTY: { | |
2737 BuildKeyedSuperPropertyStore(object); | |
2738 break; | |
2739 } | |
2524 } | 2740 } |
2525 | 2741 |
2526 // Restore old value for postfix expressions. | 2742 // Restore old value for postfix expressions. |
2527 if (is_postfix) { | 2743 if (is_postfix) { |
2528 execution_result()->SetResultInRegister(old_value); | 2744 execution_result()->SetResultInRegister(old_value); |
2529 } else { | 2745 } else { |
2530 execution_result()->SetResultInAccumulator(); | 2746 execution_result()->SetResultInAccumulator(); |
2531 } | 2747 } |
2532 } | 2748 } |
2533 | 2749 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2573 UNREACHABLE(); | 2789 UNREACHABLE(); |
2574 } | 2790 } |
2575 | 2791 |
2576 | 2792 |
2577 void BytecodeGenerator::VisitThisFunction(ThisFunction* expr) { | 2793 void BytecodeGenerator::VisitThisFunction(ThisFunction* expr) { |
2578 execution_result()->SetResultInRegister(Register::function_closure()); | 2794 execution_result()->SetResultInRegister(Register::function_closure()); |
2579 } | 2795 } |
2580 | 2796 |
2581 | 2797 |
2582 void BytecodeGenerator::VisitSuperCallReference(SuperCallReference* expr) { | 2798 void BytecodeGenerator::VisitSuperCallReference(SuperCallReference* expr) { |
2583 UNIMPLEMENTED(); | 2799 // Handled by VisitCall(). |
2800 UNREACHABLE(); | |
2584 } | 2801 } |
2585 | 2802 |
2586 | 2803 |
2587 void BytecodeGenerator::VisitSuperPropertyReference( | 2804 void BytecodeGenerator::VisitSuperPropertyReference( |
2588 SuperPropertyReference* expr) { | 2805 SuperPropertyReference* expr) { |
2589 UNIMPLEMENTED(); | 2806 builder()->CallRuntime(Runtime::kThrowUnsupportedSuperError, Register(0), 0); |
2807 execution_result()->SetResultInAccumulator(); | |
2590 } | 2808 } |
2591 | 2809 |
2592 | 2810 |
2593 void BytecodeGenerator::VisitCommaExpression(BinaryOperation* binop) { | 2811 void BytecodeGenerator::VisitCommaExpression(BinaryOperation* binop) { |
2594 VisitForEffect(binop->left()); | 2812 VisitForEffect(binop->left()); |
2595 Visit(binop->right()); | 2813 Visit(binop->right()); |
2596 } | 2814 } |
2597 | 2815 |
2598 | 2816 |
2599 void BytecodeGenerator::VisitLogicalOrExpression(BinaryOperation* binop) { | 2817 void BytecodeGenerator::VisitLogicalOrExpression(BinaryOperation* binop) { |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2752 // TODO(rmcilroy): Replace value_out with VisitForRegister(); | 2970 // TODO(rmcilroy): Replace value_out with VisitForRegister(); |
2753 if (property == nullptr) { | 2971 if (property == nullptr) { |
2754 builder()->LoadNull().StoreAccumulatorInRegister(value_out); | 2972 builder()->LoadNull().StoreAccumulatorInRegister(value_out); |
2755 } else { | 2973 } else { |
2756 VisitForAccumulatorValue(property->value()); | 2974 VisitForAccumulatorValue(property->value()); |
2757 builder()->StoreAccumulatorInRegister(value_out); | 2975 builder()->StoreAccumulatorInRegister(value_out); |
2758 VisitSetHomeObject(value_out, home_object, property); | 2976 VisitSetHomeObject(value_out, home_object, property); |
2759 } | 2977 } |
2760 } | 2978 } |
2761 | 2979 |
2762 | |
2763 void BytecodeGenerator::VisitSetHomeObject(Register value, Register home_object, | 2980 void BytecodeGenerator::VisitSetHomeObject(Register value, Register home_object, |
2764 ObjectLiteralProperty* property, | 2981 ObjectLiteralProperty* property, |
2765 int slot_number) { | 2982 int slot_number) { |
2766 Expression* expr = property->value(); | 2983 Expression* expr = property->value(); |
2767 if (!FunctionLiteral::NeedsHomeObject(expr)) return; | 2984 if (FunctionLiteral::NeedsHomeObject(expr)) { |
2768 | 2985 Handle<Name> name = isolate()->factory()->home_object_symbol(); |
2769 UNIMPLEMENTED(); | 2986 FeedbackVectorSlot slot = property->GetSlot(slot_number); |
2987 builder() | |
2988 ->LoadAccumulatorWithRegister(home_object) | |
2989 .StoreNamedProperty(value, name, feedback_index(slot), language_mode()); | |
2990 } | |
2770 } | 2991 } |
2771 | 2992 |
2772 | 2993 |
2773 void BytecodeGenerator::VisitArgumentsObject(Variable* variable) { | 2994 void BytecodeGenerator::VisitArgumentsObject(Variable* variable) { |
2774 if (variable == nullptr) return; | 2995 if (variable == nullptr) return; |
2775 | 2996 |
2776 DCHECK(variable->IsContextSlot() || variable->IsStackAllocated()); | 2997 DCHECK(variable->IsContextSlot() || variable->IsStackAllocated()); |
2777 | 2998 |
2778 // Allocate and initialize a new arguments object and assign to the | 2999 // Allocate and initialize a new arguments object and assign to the |
2779 // {arguments} variable. | 3000 // {arguments} variable. |
(...skipping 12 matching lines...) Expand all Loading... | |
2792 // Allocate and initialize a new rest parameter and assign to the {rest} | 3013 // Allocate and initialize a new rest parameter and assign to the {rest} |
2793 // variable. | 3014 // variable. |
2794 builder()->CreateArguments(CreateArgumentsType::kRestParameter); | 3015 builder()->CreateArguments(CreateArgumentsType::kRestParameter); |
2795 DCHECK(rest->IsContextSlot() || rest->IsStackAllocated()); | 3016 DCHECK(rest->IsContextSlot() || rest->IsStackAllocated()); |
2796 VisitVariableAssignment(rest, Token::ASSIGN, FeedbackVectorSlot::Invalid()); | 3017 VisitVariableAssignment(rest, Token::ASSIGN, FeedbackVectorSlot::Invalid()); |
2797 } | 3018 } |
2798 | 3019 |
2799 void BytecodeGenerator::VisitThisFunctionVariable(Variable* variable) { | 3020 void BytecodeGenerator::VisitThisFunctionVariable(Variable* variable) { |
2800 if (variable == nullptr) return; | 3021 if (variable == nullptr) return; |
2801 | 3022 |
2802 // TODO(rmcilroy): Remove once we have tests which exercise this code path. | |
2803 UNIMPLEMENTED(); | |
2804 | |
2805 // Store the closure we were called with in the given variable. | 3023 // Store the closure we were called with in the given variable. |
2806 builder()->LoadAccumulatorWithRegister(Register::function_closure()); | 3024 builder()->LoadAccumulatorWithRegister(Register::function_closure()); |
2807 VisitVariableAssignment(variable, Token::INIT, FeedbackVectorSlot::Invalid()); | 3025 VisitVariableAssignment(variable, Token::INIT, FeedbackVectorSlot::Invalid()); |
2808 } | 3026 } |
2809 | 3027 |
2810 | 3028 |
2811 void BytecodeGenerator::VisitNewTargetVariable(Variable* variable) { | 3029 void BytecodeGenerator::VisitNewTargetVariable(Variable* variable) { |
2812 if (variable == nullptr) return; | 3030 if (variable == nullptr) return; |
2813 | 3031 |
2814 // Store the new target we were called with in the given variable. | 3032 // Store the new target we were called with in the given variable. |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2891 } | 3109 } |
2892 | 3110 |
2893 | 3111 |
2894 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 3112 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
2895 return info()->feedback_vector()->GetIndex(slot); | 3113 return info()->feedback_vector()->GetIndex(slot); |
2896 } | 3114 } |
2897 | 3115 |
2898 } // namespace interpreter | 3116 } // namespace interpreter |
2899 } // namespace internal | 3117 } // namespace internal |
2900 } // namespace v8 | 3118 } // namespace v8 |
OLD | NEW |