Chromium Code Reviews| 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 1017 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1028 RegisterAllocationScope register_scope(this); | 1028 RegisterAllocationScope register_scope(this); |
| 1029 Register value = register_allocator()->NewRegister(); | 1029 Register value = register_allocator()->NewRegister(); |
| 1030 builder()->StoreAccumulatorInRegister(value); | 1030 builder()->StoreAccumulatorInRegister(value); |
| 1031 Register object = VisitForRegisterValue(property->obj()); | 1031 Register object = VisitForRegisterValue(property->obj()); |
| 1032 Register key = VisitForRegisterValue(property->key()); | 1032 Register key = VisitForRegisterValue(property->key()); |
| 1033 builder()->LoadAccumulatorWithRegister(value); | 1033 builder()->LoadAccumulatorWithRegister(value); |
| 1034 builder()->StoreKeyedProperty(object, key, feedback_index(slot), | 1034 builder()->StoreKeyedProperty(object, key, feedback_index(slot), |
| 1035 language_mode()); | 1035 language_mode()); |
| 1036 break; | 1036 break; |
| 1037 } | 1037 } |
| 1038 case NAMED_SUPER_PROPERTY: | 1038 case NAMED_SUPER_PROPERTY: { |
| 1039 case KEYED_SUPER_PROPERTY: | 1039 RegisterAllocationScope register_scope(this); |
| 1040 UNIMPLEMENTED(); | 1040 Register value = register_allocator()->NewRegister(); |
| 1041 builder()->StoreAccumulatorInRegister(value); | |
| 1042 SuperPropertyReference* super_property = | |
| 1043 property->obj()->AsSuperPropertyReference(); | |
| 1044 Register receiver = VisitForRegisterValue(super_property->this_var()); | |
| 1045 Register home_object = | |
| 1046 VisitForRegisterValue(super_property->home_object()); | |
| 1047 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | |
| 1048 builder()->LoadAccumulatorWithRegister(value); | |
| 1049 BuildNamedSuperStore(receiver, home_object, name); | |
|
rmcilroy
2016/02/11 15:25:49
Could you adapt this function to expect the home_o
oth
2016/02/12 14:12:53
I'd wondered about this too. Have added PrepareNam
| |
| 1050 break; | |
| 1051 } | |
| 1052 case KEYED_SUPER_PROPERTY: { | |
| 1053 SuperPropertyReference* super_property = | |
| 1054 property->obj()->AsSuperPropertyReference(); | |
| 1055 RegisterAllocationScope register_scope(this); | |
| 1056 Register value = register_allocator()->NewRegister(); | |
| 1057 builder()->StoreAccumulatorInRegister(value); | |
| 1058 Register receiver = VisitForRegisterValue(super_property->this_var()); | |
| 1059 Register home_object = | |
| 1060 VisitForRegisterValue(super_property->home_object()); | |
| 1061 Register key = VisitForRegisterValue(property->key()); | |
| 1062 builder()->LoadAccumulatorWithRegister(value); | |
| 1063 BuildKeyedSuperStore(receiver, home_object, key); | |
|
rmcilroy
2016/02/11 15:25:49
ditto
oth
2016/02/12 14:12:53
Acknowledged.
| |
| 1064 break; | |
| 1065 } | |
| 1041 } | 1066 } |
| 1042 } | 1067 } |
| 1043 | 1068 |
| 1044 | 1069 |
| 1045 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) { | 1070 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) { |
| 1046 if (stmt->subject()->IsNullLiteral() || | 1071 if (stmt->subject()->IsNullLiteral() || |
| 1047 stmt->subject()->IsUndefinedLiteral(isolate())) { | 1072 stmt->subject()->IsUndefinedLiteral(isolate())) { |
| 1048 // ForIn generates lots of code, skip if it wouldn't produce any effects. | 1073 // ForIn generates lots of code, skip if it wouldn't produce any effects. |
| 1049 return; | 1074 return; |
| 1050 } | 1075 } |
| (...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1472 UNREACHABLE(); | 1497 UNREACHABLE(); |
| 1473 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1498 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1474 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1499 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); |
| 1475 // Fall through. | 1500 // Fall through. |
| 1476 case ObjectLiteral::Property::COMPUTED: { | 1501 case ObjectLiteral::Property::COMPUTED: { |
| 1477 // It is safe to use [[Put]] here because the boilerplate already | 1502 // It is safe to use [[Put]] here because the boilerplate already |
| 1478 // contains computed properties with an uninitialized value. | 1503 // contains computed properties with an uninitialized value. |
| 1479 if (literal_key->value()->IsInternalizedString()) { | 1504 if (literal_key->value()->IsInternalizedString()) { |
| 1480 if (property->emit_store()) { | 1505 if (property->emit_store()) { |
| 1481 VisitForAccumulatorValue(property->value()); | 1506 VisitForAccumulatorValue(property->value()); |
| 1482 builder()->StoreNamedProperty( | 1507 if (FunctionLiteral::NeedsHomeObject(property->value())) { |
| 1483 literal, literal_key->AsPropertyName(), | 1508 RegisterAllocationScope register_scope(this); |
| 1484 feedback_index(property->GetSlot(0)), language_mode()); | 1509 Register value = register_allocator()->NewRegister(); |
| 1510 builder()->StoreAccumulatorInRegister(value); | |
| 1511 builder()->StoreNamedProperty( | |
| 1512 literal, literal_key->AsPropertyName(), | |
| 1513 feedback_index(property->GetSlot(0)), language_mode()); | |
| 1514 VisitSetHomeObject(value, literal, property, 1); | |
| 1515 } else { | |
| 1516 builder()->StoreNamedProperty( | |
| 1517 literal, literal_key->AsPropertyName(), | |
| 1518 feedback_index(property->GetSlot(0)), language_mode()); | |
| 1519 } | |
| 1485 } else { | 1520 } else { |
| 1486 VisitForEffect(property->value()); | 1521 VisitForEffect(property->value()); |
| 1487 } | 1522 } |
| 1488 } else { | 1523 } else { |
| 1489 register_allocator()->PrepareForConsecutiveAllocations(4); | 1524 register_allocator()->PrepareForConsecutiveAllocations(4); |
| 1490 Register literal_argument = | 1525 Register literal_argument = |
| 1491 register_allocator()->NextConsecutiveRegister(); | 1526 register_allocator()->NextConsecutiveRegister(); |
| 1492 Register key = register_allocator()->NextConsecutiveRegister(); | 1527 Register key = register_allocator()->NextConsecutiveRegister(); |
| 1493 Register value = register_allocator()->NextConsecutiveRegister(); | 1528 Register value = register_allocator()->NextConsecutiveRegister(); |
| 1494 Register language = register_allocator()->NextConsecutiveRegister(); | 1529 Register language = register_allocator()->NextConsecutiveRegister(); |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1762 } | 1797 } |
| 1763 | 1798 |
| 1764 | 1799 |
| 1765 Register BytecodeGenerator::VisitVariableLoadForRegisterValue( | 1800 Register BytecodeGenerator::VisitVariableLoadForRegisterValue( |
| 1766 Variable* variable, FeedbackVectorSlot slot, TypeofMode typeof_mode) { | 1801 Variable* variable, FeedbackVectorSlot slot, TypeofMode typeof_mode) { |
| 1767 RegisterResultScope register_scope(this); | 1802 RegisterResultScope register_scope(this); |
| 1768 VisitVariableLoad(variable, slot, typeof_mode); | 1803 VisitVariableLoad(variable, slot, typeof_mode); |
| 1769 return register_scope.ResultRegister(); | 1804 return register_scope.ResultRegister(); |
| 1770 } | 1805 } |
| 1771 | 1806 |
| 1807 void BytecodeGenerator::BuildKeyedSuperLoad(Register receiver, | |
|
rmcilroy
2016/02/11 15:25:49
BuildKeyedSuperPropertyLoad (and the same for the
oth
2016/02/12 14:12:53
Done.
| |
| 1808 Register home_object, | |
| 1809 Register key) { | |
| 1810 RegisterAllocationScope register_scope(this); | |
| 1811 Register args[4]; | |
| 1812 register_allocator()->PrepareForConsecutiveAllocations(arraysize(args)); | |
| 1813 for (size_t i = 0; i < arraysize(args); i++) { | |
| 1814 args[i] = register_allocator()->NextConsecutiveRegister(); | |
| 1815 } | |
|
rmcilroy
2016/02/11 15:25:49
I'd prefer just to explicitly name each of the reg
oth
2016/02/12 14:12:53
Keeping this pattern as discussed and incorporated
| |
| 1816 | |
| 1817 builder() | |
| 1818 ->LoadLiteral(Smi::FromInt(static_cast<int>(language_mode()))) | |
| 1819 .StoreAccumulatorInRegister(args[3]) | |
| 1820 .MoveRegister(key, args[2]) | |
| 1821 .MoveRegister(home_object, args[1]) | |
| 1822 .MoveRegister(receiver, args[0]) | |
| 1823 .CallRuntime(Runtime::kLoadKeyedFromSuper, args[0], | |
| 1824 static_cast<int>(arraysize(args))); | |
| 1825 } | |
| 1826 | |
| 1827 void BytecodeGenerator::BuildKeyedSuperStore(Register receiver, | |
| 1828 Register home_object, | |
| 1829 Register key) { | |
| 1830 RegisterAllocationScope register_scope(this); | |
| 1831 Register args[4]; | |
| 1832 register_allocator()->PrepareForConsecutiveAllocations(arraysize(args)); | |
| 1833 for (size_t i = 0; i < arraysize(args); i++) { | |
| 1834 args[i] = register_allocator()->NextConsecutiveRegister(); | |
| 1835 } | |
| 1836 | |
| 1837 // Prepare arguments. Value to be stored is in the accumulator. | |
| 1838 builder() | |
| 1839 ->StoreAccumulatorInRegister(args[3]) | |
| 1840 .MoveRegister(key, args[2]) | |
| 1841 .MoveRegister(home_object, args[1]) | |
| 1842 .MoveRegister(receiver, args[0]); | |
| 1843 | |
| 1844 // Call runtime to perform store. | |
| 1845 Runtime::FunctionId function_id = is_strict(language_mode()) | |
| 1846 ? Runtime::kStoreKeyedToSuper_Strict | |
| 1847 : Runtime::kStoreKeyedToSuper_Sloppy; | |
| 1848 builder()->CallRuntime(function_id, args[0], | |
| 1849 static_cast<int>(arraysize(args))); | |
| 1850 } | |
| 1851 | |
| 1852 void BytecodeGenerator::BuildNamedSuperLoad(Register receiver, | |
| 1853 Register home_object, | |
| 1854 Handle<Name> name) { | |
| 1855 RegisterAllocationScope register_scope(this); | |
| 1856 Register args[4]; | |
| 1857 register_allocator()->PrepareForConsecutiveAllocations(arraysize(args)); | |
| 1858 for (size_t i = 0; i < arraysize(args); i++) { | |
| 1859 args[i] = register_allocator()->NextConsecutiveRegister(); | |
| 1860 } | |
| 1861 | |
| 1862 builder() | |
| 1863 ->LoadLiteral(Smi::FromInt(static_cast<int>(language_mode()))) | |
| 1864 .StoreAccumulatorInRegister(args[3]) | |
| 1865 .LoadLiteral(name) | |
| 1866 .StoreAccumulatorInRegister(args[2]) | |
| 1867 .MoveRegister(home_object, args[1]) | |
| 1868 .MoveRegister(receiver, args[0]) | |
| 1869 .CallRuntime(Runtime::kLoadFromSuper, args[0], | |
| 1870 static_cast<int>(arraysize(args))); | |
| 1871 } | |
| 1872 | |
| 1873 void BytecodeGenerator::BuildNamedSuperStore(Register receiver, | |
| 1874 Register home_object, | |
| 1875 Handle<Name> name) { | |
| 1876 RegisterAllocationScope register_scope(this); | |
| 1877 Register args[4]; | |
| 1878 register_allocator()->PrepareForConsecutiveAllocations(arraysize(args)); | |
| 1879 for (size_t i = 0; i < arraysize(args); i++) { | |
| 1880 args[i] = register_allocator()->NextConsecutiveRegister(); | |
| 1881 } | |
| 1882 | |
| 1883 // Prepare arguments. Value to be stored is in the accumulator. | |
| 1884 builder() | |
| 1885 ->StoreAccumulatorInRegister(args[3]) | |
| 1886 .LoadLiteral(name) | |
| 1887 .StoreAccumulatorInRegister(args[2]) | |
| 1888 .MoveRegister(home_object, args[1]) | |
| 1889 .MoveRegister(receiver, args[0]); | |
| 1890 | |
| 1891 // Call runtime to perform store. | |
| 1892 Runtime::FunctionId function_id = is_strict(language_mode()) | |
| 1893 ? Runtime::kStoreToSuper_Strict | |
| 1894 : Runtime::kStoreToSuper_Sloppy; | |
| 1895 builder()->CallRuntime(function_id, args[0], | |
| 1896 static_cast<int>(arraysize(args))); | |
| 1897 } | |
| 1898 | |
| 1772 void BytecodeGenerator::BuildThrowIfHole(Handle<String> name) { | 1899 void BytecodeGenerator::BuildThrowIfHole(Handle<String> name) { |
| 1773 Register name_reg = register_allocator()->NewRegister(); | 1900 Register name_reg = register_allocator()->NewRegister(); |
| 1774 BytecodeLabel end_label; | 1901 BytecodeLabel end_label; |
| 1775 // TODO(mythria): This will be replaced by a new bytecode that throws an | 1902 // TODO(mythria): This will be replaced by a new bytecode that throws an |
| 1776 // error if the value is the hole. | 1903 // error if the value is the hole. |
| 1777 builder() | 1904 builder() |
| 1778 ->JumpIfNotHole(&end_label) | 1905 ->JumpIfNotHole(&end_label) |
| 1779 .LoadLiteral(name) | 1906 .LoadLiteral(name) |
| 1780 .StoreAccumulatorInRegister(name_reg) | 1907 .StoreAccumulatorInRegister(name_reg) |
| 1781 .CallRuntime(Runtime::kThrowReferenceError, name_reg, 1) | 1908 .CallRuntime(Runtime::kThrowReferenceError, name_reg, 1) |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1970 } else { | 2097 } else { |
| 1971 builder()->StoreLookupSlot(variable->name(), language_mode()); | 2098 builder()->StoreLookupSlot(variable->name(), language_mode()); |
| 1972 } | 2099 } |
| 1973 break; | 2100 break; |
| 1974 } | 2101 } |
| 1975 } | 2102 } |
| 1976 } | 2103 } |
| 1977 | 2104 |
| 1978 | 2105 |
| 1979 void BytecodeGenerator::VisitAssignment(Assignment* expr) { | 2106 void BytecodeGenerator::VisitAssignment(Assignment* expr) { |
| 1980 DCHECK(expr->target()->IsValidReferenceExpression()); | 2107 DCHECK(expr->target()->IsValidReferenceExpressionOrThis()); |
| 1981 Register object, key; | 2108 Register home_object, object, key; |
| 1982 Handle<String> name; | 2109 Handle<String> name; |
| 1983 | 2110 |
| 1984 // Left-hand side can only be a property, a global or a variable slot. | 2111 // Left-hand side can only be a property, a global or a variable slot. |
| 1985 Property* property = expr->target()->AsProperty(); | 2112 Property* property = expr->target()->AsProperty(); |
| 1986 LhsKind assign_type = Property::GetAssignType(property); | 2113 LhsKind assign_type = Property::GetAssignType(property); |
| 1987 | 2114 |
| 1988 // Evaluate LHS expression. | 2115 // Evaluate LHS expression. |
| 1989 switch (assign_type) { | 2116 switch (assign_type) { |
| 1990 case VARIABLE: | 2117 case VARIABLE: |
| 1991 // Nothing to do to evaluate variable assignment LHS. | 2118 // Nothing to do to evaluate variable assignment LHS. |
| 1992 break; | 2119 break; |
| 1993 case NAMED_PROPERTY: { | 2120 case NAMED_PROPERTY: { |
| 1994 object = VisitForRegisterValue(property->obj()); | 2121 object = VisitForRegisterValue(property->obj()); |
| 1995 name = property->key()->AsLiteral()->AsPropertyName(); | 2122 name = property->key()->AsLiteral()->AsPropertyName(); |
| 1996 break; | 2123 break; |
| 1997 } | 2124 } |
| 1998 case KEYED_PROPERTY: { | 2125 case KEYED_PROPERTY: { |
| 1999 object = VisitForRegisterValue(property->obj()); | 2126 object = VisitForRegisterValue(property->obj()); |
| 2000 if (expr->is_compound()) { | 2127 if (expr->is_compound()) { |
| 2001 // Use VisitForAccumulator and store to register so that the key is | 2128 // Use VisitForAccumulator and store to register so that the key is |
| 2002 // still in the accumulator for loading the old value below. | 2129 // still in the accumulator for loading the old value below. |
| 2003 key = register_allocator()->NewRegister(); | 2130 key = register_allocator()->NewRegister(); |
| 2004 VisitForAccumulatorValue(property->key()); | 2131 VisitForAccumulatorValue(property->key()); |
| 2005 builder()->StoreAccumulatorInRegister(key); | 2132 builder()->StoreAccumulatorInRegister(key); |
| 2006 } else { | 2133 } else { |
| 2007 key = VisitForRegisterValue(property->key()); | 2134 key = VisitForRegisterValue(property->key()); |
| 2008 } | 2135 } |
| 2009 break; | 2136 break; |
| 2010 } | 2137 } |
| 2011 case NAMED_SUPER_PROPERTY: | 2138 case NAMED_SUPER_PROPERTY: { |
| 2012 case KEYED_SUPER_PROPERTY: | 2139 object = VisitForRegisterValue( |
| 2013 UNIMPLEMENTED(); | 2140 property->obj()->AsSuperPropertyReference()->this_var()); |
| 2141 home_object = VisitForRegisterValue( | |
| 2142 property->obj()->AsSuperPropertyReference()->home_object()); | |
| 2143 name = property->key()->AsLiteral()->AsPropertyName(); | |
| 2144 break; | |
| 2145 } | |
| 2146 case KEYED_SUPER_PROPERTY: { | |
| 2147 object = VisitForRegisterValue( | |
| 2148 property->obj()->AsSuperPropertyReference()->this_var()); | |
| 2149 home_object = VisitForRegisterValue( | |
| 2150 property->obj()->AsSuperPropertyReference()->home_object()); | |
| 2151 key = VisitForRegisterValue(property->key()); | |
| 2152 break; | |
| 2153 } | |
| 2014 } | 2154 } |
| 2015 | 2155 |
| 2016 // Evaluate the value and potentially handle compound assignments by loading | 2156 // Evaluate the value and potentially handle compound assignments by loading |
| 2017 // the left-hand side value and performing a binary operation. | 2157 // the left-hand side value and performing a binary operation. |
| 2018 if (expr->is_compound()) { | 2158 if (expr->is_compound()) { |
| 2019 Register old_value; | 2159 Register old_value; |
| 2020 switch (assign_type) { | 2160 switch (assign_type) { |
| 2021 case VARIABLE: { | 2161 case VARIABLE: { |
| 2022 VariableProxy* proxy = expr->target()->AsVariableProxy(); | 2162 VariableProxy* proxy = expr->target()->AsVariableProxy(); |
| 2023 old_value = VisitVariableLoadForRegisterValue( | 2163 old_value = VisitVariableLoadForRegisterValue( |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 2036 case KEYED_PROPERTY: { | 2176 case KEYED_PROPERTY: { |
| 2037 // Key is already in accumulator at this point due to evaluating the | 2177 // Key is already in accumulator at this point due to evaluating the |
| 2038 // LHS above. | 2178 // LHS above. |
| 2039 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); | 2179 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); |
| 2040 old_value = register_allocator()->NewRegister(); | 2180 old_value = register_allocator()->NewRegister(); |
| 2041 builder() | 2181 builder() |
| 2042 ->LoadKeyedProperty(object, feedback_index(slot), language_mode()) | 2182 ->LoadKeyedProperty(object, feedback_index(slot), language_mode()) |
| 2043 .StoreAccumulatorInRegister(old_value); | 2183 .StoreAccumulatorInRegister(old_value); |
| 2044 break; | 2184 break; |
| 2045 } | 2185 } |
| 2046 case NAMED_SUPER_PROPERTY: | 2186 case NAMED_SUPER_PROPERTY: { |
| 2047 case KEYED_SUPER_PROPERTY: | 2187 old_value = register_allocator()->NewRegister(); |
| 2048 UNIMPLEMENTED(); | 2188 BuildNamedSuperLoad(object, home_object, name); |
| 2189 builder()->StoreAccumulatorInRegister(old_value); | |
| 2049 break; | 2190 break; |
| 2191 } | |
| 2192 case KEYED_SUPER_PROPERTY: { | |
| 2193 old_value = register_allocator()->NewRegister(); | |
| 2194 BuildKeyedSuperLoad(object, home_object, key); | |
| 2195 builder()->StoreAccumulatorInRegister(old_value); | |
| 2196 break; | |
| 2197 } | |
| 2050 } | 2198 } |
| 2051 VisitForAccumulatorValue(expr->value()); | 2199 VisitForAccumulatorValue(expr->value()); |
| 2052 builder()->BinaryOperation(expr->binary_op(), old_value, | 2200 builder()->BinaryOperation(expr->binary_op(), old_value, |
| 2053 language_mode_strength()); | 2201 language_mode_strength()); |
| 2054 } else { | 2202 } else { |
| 2055 VisitForAccumulatorValue(expr->value()); | 2203 VisitForAccumulatorValue(expr->value()); |
| 2056 } | 2204 } |
| 2057 | 2205 |
| 2058 // Store the value. | 2206 // Store the value. |
| 2059 FeedbackVectorSlot slot = expr->AssignmentSlot(); | 2207 FeedbackVectorSlot slot = expr->AssignmentSlot(); |
| 2060 switch (assign_type) { | 2208 switch (assign_type) { |
| 2061 case VARIABLE: { | 2209 case VARIABLE: { |
| 2062 // TODO(oth): The VisitVariableAssignment() call is hard to reason about. | 2210 // TODO(oth): The VisitVariableAssignment() call is hard to reason about. |
| 2063 // Is the value in the accumulator safe? Yes, but scary. | 2211 // Is the value in the accumulator safe? Yes, but scary. |
| 2064 Variable* variable = expr->target()->AsVariableProxy()->var(); | 2212 Variable* variable = expr->target()->AsVariableProxy()->var(); |
| 2065 VisitVariableAssignment(variable, expr->op(), slot); | 2213 VisitVariableAssignment(variable, expr->op(), slot); |
| 2066 break; | 2214 break; |
| 2067 } | 2215 } |
| 2068 case NAMED_PROPERTY: | 2216 case NAMED_PROPERTY: |
| 2069 builder()->StoreNamedProperty(object, name, feedback_index(slot), | 2217 builder()->StoreNamedProperty(object, name, feedback_index(slot), |
| 2070 language_mode()); | 2218 language_mode()); |
| 2071 break; | 2219 break; |
| 2072 case KEYED_PROPERTY: | 2220 case KEYED_PROPERTY: |
| 2073 builder()->StoreKeyedProperty(object, key, feedback_index(slot), | 2221 builder()->StoreKeyedProperty(object, key, feedback_index(slot), |
| 2074 language_mode()); | 2222 language_mode()); |
| 2075 break; | 2223 break; |
| 2076 case NAMED_SUPER_PROPERTY: | 2224 case NAMED_SUPER_PROPERTY: { |
| 2077 case KEYED_SUPER_PROPERTY: | 2225 BuildNamedSuperStore(object, home_object, name); |
| 2078 UNIMPLEMENTED(); | 2226 break; |
| 2227 } | |
| 2228 case KEYED_SUPER_PROPERTY: { | |
| 2229 BuildKeyedSuperStore(object, home_object, key); | |
| 2230 break; | |
| 2231 } | |
| 2079 } | 2232 } |
| 2080 execution_result()->SetResultInAccumulator(); | 2233 execution_result()->SetResultInAccumulator(); |
| 2081 } | 2234 } |
| 2082 | 2235 |
| 2083 | 2236 |
| 2084 void BytecodeGenerator::VisitYield(Yield* expr) { UNIMPLEMENTED(); } | 2237 void BytecodeGenerator::VisitYield(Yield* expr) { UNIMPLEMENTED(); } |
| 2085 | 2238 |
| 2086 | 2239 |
| 2087 void BytecodeGenerator::VisitThrow(Throw* expr) { | 2240 void BytecodeGenerator::VisitThrow(Throw* expr) { |
| 2088 VisitForAccumulatorValue(expr->exception()); | 2241 VisitForAccumulatorValue(expr->exception()); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 2106 expr->key()->AsLiteral()->AsPropertyName(), | 2259 expr->key()->AsLiteral()->AsPropertyName(), |
| 2107 feedback_index(slot), language_mode()); | 2260 feedback_index(slot), language_mode()); |
| 2108 break; | 2261 break; |
| 2109 } | 2262 } |
| 2110 case KEYED_PROPERTY: { | 2263 case KEYED_PROPERTY: { |
| 2111 VisitForAccumulatorValue(expr->key()); | 2264 VisitForAccumulatorValue(expr->key()); |
| 2112 builder()->LoadKeyedProperty(obj, feedback_index(slot), language_mode()); | 2265 builder()->LoadKeyedProperty(obj, feedback_index(slot), language_mode()); |
| 2113 break; | 2266 break; |
| 2114 } | 2267 } |
| 2115 case NAMED_SUPER_PROPERTY: | 2268 case NAMED_SUPER_PROPERTY: |
| 2269 VisitNamedSuperPropertyLoad(expr, Register::invalid_value()); | |
| 2270 break; | |
| 2116 case KEYED_SUPER_PROPERTY: | 2271 case KEYED_SUPER_PROPERTY: |
| 2117 UNIMPLEMENTED(); | 2272 VisitKeyedSuperPropertyLoad(expr, Register::invalid_value()); |
| 2273 break; | |
| 2118 } | 2274 } |
| 2119 execution_result()->SetResultInAccumulator(); | 2275 execution_result()->SetResultInAccumulator(); |
| 2120 } | 2276 } |
| 2121 | 2277 |
| 2122 | |
| 2123 void BytecodeGenerator::VisitPropertyLoadForAccumulator(Register obj, | 2278 void BytecodeGenerator::VisitPropertyLoadForAccumulator(Register obj, |
| 2124 Property* expr) { | 2279 Property* expr) { |
| 2125 AccumulatorResultScope result_scope(this); | 2280 AccumulatorResultScope result_scope(this); |
| 2126 VisitPropertyLoad(obj, expr); | 2281 VisitPropertyLoad(obj, expr); |
| 2127 } | 2282 } |
| 2128 | 2283 |
| 2284 void BytecodeGenerator::VisitNamedSuperPropertyLoad(Property* property, | |
| 2285 Register receiver_out) { | |
| 2286 RegisterAllocationScope register_scope(this); | |
| 2287 register_allocator()->PrepareForConsecutiveAllocations(4); | |
| 2288 Register receiver = register_allocator()->NextConsecutiveRegister(); | |
| 2289 Register home_object = register_allocator()->NextConsecutiveRegister(); | |
| 2290 Register property_name = register_allocator()->NextConsecutiveRegister(); | |
| 2291 Register language = register_allocator()->NextConsecutiveRegister(); | |
| 2292 | |
| 2293 SuperPropertyReference* super_ref = | |
| 2294 property->obj()->AsSuperPropertyReference(); | |
| 2295 Expression* key = property->key(); | |
| 2296 VisitForAccumulatorValue(super_ref->this_var()); | |
| 2297 builder()->StoreAccumulatorInRegister(receiver); | |
| 2298 | |
| 2299 VisitForAccumulatorValue(super_ref->home_object()); | |
|
rmcilroy
2016/02/11 15:25:49
Could you use BuildNamedSuperLoad here?
oth
2016/02/12 14:12:53
Done.
| |
| 2300 builder() | |
| 2301 ->StoreAccumulatorInRegister(home_object) | |
| 2302 .LoadLiteral(key->AsLiteral()->AsPropertyName()) | |
| 2303 .StoreAccumulatorInRegister(property_name) | |
| 2304 .LoadLiteral(Smi::FromInt(static_cast<int>(language_mode()))) | |
| 2305 .StoreAccumulatorInRegister(language); | |
| 2306 builder()->CallRuntime(Runtime::kLoadFromSuper, receiver, 4); | |
| 2307 if (receiver_out.is_valid()) { | |
|
rmcilroy
2016/02/11 15:25:49
nit - move this up to be below "builder()->StoreAc
oth
2016/02/12 14:12:53
Done.
| |
| 2308 builder()->MoveRegister(receiver, receiver_out); | |
| 2309 } | |
| 2310 } | |
| 2311 | |
| 2312 void BytecodeGenerator::VisitKeyedSuperPropertyLoad(Property* property, | |
| 2313 Register receiver_out) { | |
| 2314 RegisterAllocationScope register_scope(this); | |
|
rmcilroy
2016/02/11 15:25:49
Same question here, could this use BuildKeyedSuper
oth
2016/02/12 14:12:53
Done.
| |
| 2315 register_allocator()->PrepareForConsecutiveAllocations(4); | |
| 2316 Register receiver = register_allocator()->NextConsecutiveRegister(); | |
| 2317 Register home = register_allocator()->NextConsecutiveRegister(); | |
| 2318 Register key = register_allocator()->NextConsecutiveRegister(); | |
| 2319 Register language = register_allocator()->NextConsecutiveRegister(); | |
| 2320 | |
| 2321 SuperPropertyReference* super_ref = | |
| 2322 property->obj()->AsSuperPropertyReference(); | |
| 2323 VisitForAccumulatorValue(super_ref->home_object()); | |
| 2324 builder()->StoreAccumulatorInRegister(home); | |
| 2325 | |
| 2326 VisitForAccumulatorValue(super_ref->this_var()); | |
| 2327 builder()->StoreAccumulatorInRegister(receiver); | |
| 2328 | |
| 2329 VisitForAccumulatorValue(property->key()); | |
| 2330 builder()->StoreAccumulatorInRegister(key); | |
| 2331 | |
| 2332 builder() | |
| 2333 ->LoadLiteral(Smi::FromInt(static_cast<int>(language_mode()))) | |
| 2334 .StoreAccumulatorInRegister(language); | |
| 2335 | |
| 2336 builder()->CallRuntime(Runtime::kLoadKeyedFromSuper, receiver, 4); | |
| 2337 if (receiver_out.is_valid()) { | |
| 2338 builder()->MoveRegister(receiver, receiver_out); | |
| 2339 } | |
| 2340 } | |
| 2129 | 2341 |
| 2130 void BytecodeGenerator::VisitProperty(Property* expr) { | 2342 void BytecodeGenerator::VisitProperty(Property* expr) { |
| 2131 Register obj = VisitForRegisterValue(expr->obj()); | 2343 LhsKind property_kind = Property::GetAssignType(expr); |
| 2132 VisitPropertyLoad(obj, expr); | 2344 FeedbackVectorSlot slot = expr->PropertyFeedbackSlot(); |
|
rmcilroy
2016/02/11 15:25:49
Could you merge this back please (and make the Vi
oth
2016/02/12 14:12:53
Done.
| |
| 2345 switch (property_kind) { | |
| 2346 case VARIABLE: | |
| 2347 UNREACHABLE(); | |
| 2348 case NAMED_PROPERTY: { | |
| 2349 Register obj = VisitForRegisterValue(expr->obj()); | |
| 2350 builder()->LoadNamedProperty(obj, | |
| 2351 expr->key()->AsLiteral()->AsPropertyName(), | |
| 2352 feedback_index(slot), language_mode()); | |
| 2353 break; | |
| 2354 } | |
| 2355 case KEYED_PROPERTY: { | |
| 2356 Register obj = VisitForRegisterValue(expr->obj()); | |
| 2357 VisitForAccumulatorValue(expr->key()); | |
| 2358 builder()->LoadKeyedProperty(obj, feedback_index(slot), language_mode()); | |
| 2359 break; | |
| 2360 } | |
| 2361 case NAMED_SUPER_PROPERTY: | |
| 2362 VisitNamedSuperPropertyLoad(expr, Register::invalid_value()); | |
| 2363 break; | |
| 2364 case KEYED_SUPER_PROPERTY: | |
| 2365 VisitKeyedSuperPropertyLoad(expr, Register::invalid_value()); | |
| 2366 break; | |
| 2367 } | |
| 2368 execution_result()->SetResultInAccumulator(); | |
| 2133 } | 2369 } |
| 2134 | 2370 |
| 2135 | 2371 |
| 2136 Register BytecodeGenerator::VisitArguments(ZoneList<Expression*>* args) { | 2372 Register BytecodeGenerator::VisitArguments(ZoneList<Expression*>* args) { |
| 2137 if (args->length() == 0) { | 2373 if (args->length() == 0) { |
| 2138 return Register(); | 2374 return Register(); |
| 2139 } | 2375 } |
| 2140 | 2376 |
| 2141 // Visit arguments and place in a contiguous block of temporary | 2377 // Visit arguments and place in a contiguous block of temporary |
| 2142 // registers. Return the first temporary register corresponding to | 2378 // registers. Return the first temporary register corresponding to |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 2158 // Visit remaining arguments | 2394 // Visit remaining arguments |
| 2159 for (int i = 1; i < static_cast<int>(args->length()); i++) { | 2395 for (int i = 1; i < static_cast<int>(args->length()); i++) { |
| 2160 Register ith_arg = register_allocator()->NextConsecutiveRegister(); | 2396 Register ith_arg = register_allocator()->NextConsecutiveRegister(); |
| 2161 VisitForAccumulatorValue(args->at(i)); | 2397 VisitForAccumulatorValue(args->at(i)); |
| 2162 builder()->StoreAccumulatorInRegister(ith_arg); | 2398 builder()->StoreAccumulatorInRegister(ith_arg); |
| 2163 DCHECK(ith_arg.index() - i == first_arg.index()); | 2399 DCHECK(ith_arg.index() - i == first_arg.index()); |
| 2164 } | 2400 } |
| 2165 return first_arg; | 2401 return first_arg; |
| 2166 } | 2402 } |
| 2167 | 2403 |
| 2168 | |
| 2169 void BytecodeGenerator::VisitCall(Call* expr) { | 2404 void BytecodeGenerator::VisitCall(Call* expr) { |
| 2170 Expression* callee_expr = expr->expression(); | 2405 Expression* callee_expr = expr->expression(); |
| 2171 Call::CallType call_type = expr->GetCallType(isolate()); | 2406 Call::CallType call_type = expr->GetCallType(isolate()); |
| 2172 | 2407 |
| 2408 if (call_type == Call::SUPER_CALL) { | |
| 2409 return VisitCallSuper(expr); | |
| 2410 } | |
| 2411 | |
| 2173 // Prepare the callee and the receiver to the function call. This depends on | 2412 // Prepare the callee and the receiver to the function call. This depends on |
| 2174 // the semantics of the underlying call type. | 2413 // the semantics of the underlying call type. |
| 2175 | 2414 |
| 2176 // The receiver and arguments need to be allocated consecutively for | 2415 // The receiver and arguments need to be allocated consecutively for |
| 2177 // Call(). We allocate the callee and receiver consecutively for calls to | 2416 // Call(). We allocate the callee and receiver consecutively for calls to |
| 2178 // %LoadLookupSlotForCall. Future optimizations could avoid this there are | 2417 // %LoadLookupSlotForCall. Future optimizations could avoid this there are |
| 2179 // no arguments or the receiver and arguments are already consecutive. | 2418 // no arguments or the receiver and arguments are already consecutive. |
| 2180 ZoneList<Expression*>* args = expr->arguments(); | 2419 ZoneList<Expression*>* args = expr->arguments(); |
| 2181 register_allocator()->PrepareForConsecutiveAllocations(args->length() + 2); | 2420 register_allocator()->PrepareForConsecutiveAllocations(args->length() + 2); |
| 2182 Register callee = register_allocator()->NextConsecutiveRegister(); | 2421 Register callee = register_allocator()->NextConsecutiveRegister(); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2220 } | 2459 } |
| 2221 // Fall through. | 2460 // Fall through. |
| 2222 DCHECK_EQ(call_type, Call::POSSIBLY_EVAL_CALL); | 2461 DCHECK_EQ(call_type, Call::POSSIBLY_EVAL_CALL); |
| 2223 } | 2462 } |
| 2224 case Call::OTHER_CALL: { | 2463 case Call::OTHER_CALL: { |
| 2225 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); | 2464 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); |
| 2226 VisitForAccumulatorValue(callee_expr); | 2465 VisitForAccumulatorValue(callee_expr); |
| 2227 builder()->StoreAccumulatorInRegister(callee); | 2466 builder()->StoreAccumulatorInRegister(callee); |
| 2228 break; | 2467 break; |
| 2229 } | 2468 } |
| 2230 case Call::NAMED_SUPER_PROPERTY_CALL: | 2469 case Call::NAMED_SUPER_PROPERTY_CALL: { |
| 2231 case Call::KEYED_SUPER_PROPERTY_CALL: | 2470 Property* property = callee_expr->AsProperty(); |
| 2471 VisitNamedSuperPropertyLoad(property, receiver); | |
| 2472 builder()->StoreAccumulatorInRegister(callee); | |
| 2473 break; | |
| 2474 } | |
| 2475 case Call::KEYED_SUPER_PROPERTY_CALL: { | |
| 2476 Property* property = callee_expr->AsProperty(); | |
| 2477 VisitKeyedSuperPropertyLoad(property, receiver); | |
| 2478 builder()->StoreAccumulatorInRegister(callee); | |
| 2479 break; | |
| 2480 } | |
| 2232 case Call::SUPER_CALL: | 2481 case Call::SUPER_CALL: |
| 2233 UNIMPLEMENTED(); | 2482 UNREACHABLE(); |
| 2483 break; | |
| 2234 } | 2484 } |
| 2235 | 2485 |
| 2236 // Evaluate all arguments to the function call and store in sequential | 2486 // Evaluate all arguments to the function call and store in sequential |
| 2237 // registers. | 2487 // registers. |
| 2238 Register arg = VisitArguments(args); | 2488 Register arg = VisitArguments(args); |
| 2239 CHECK(args->length() == 0 || arg.index() == receiver.index() + 1); | 2489 CHECK(args->length() == 0 || arg.index() == receiver.index() + 1); |
| 2240 | 2490 |
| 2241 // Resolve callee for a potential direct eval call. This block will mutate the | 2491 // Resolve callee for a potential direct eval call. This block will mutate the |
| 2242 // callee value. | 2492 // callee value. |
| 2243 if (call_type == Call::POSSIBLY_EVAL_CALL && args->length() > 0) { | 2493 if (call_type == Call::POSSIBLY_EVAL_CALL && args->length() > 0) { |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 2267 ->CallRuntime(Runtime::kResolvePossiblyDirectEval, callee_for_eval, 5) | 2517 ->CallRuntime(Runtime::kResolvePossiblyDirectEval, callee_for_eval, 5) |
| 2268 .StoreAccumulatorInRegister(callee); | 2518 .StoreAccumulatorInRegister(callee); |
| 2269 } | 2519 } |
| 2270 | 2520 |
| 2271 builder()->SetExpressionPosition(expr); | 2521 builder()->SetExpressionPosition(expr); |
| 2272 builder()->Call(callee, receiver, 1 + args->length(), | 2522 builder()->Call(callee, receiver, 1 + args->length(), |
| 2273 feedback_index(expr->CallFeedbackICSlot())); | 2523 feedback_index(expr->CallFeedbackICSlot())); |
| 2274 execution_result()->SetResultInAccumulator(); | 2524 execution_result()->SetResultInAccumulator(); |
| 2275 } | 2525 } |
| 2276 | 2526 |
| 2527 void BytecodeGenerator::VisitCallSuper(Call* expr) { | |
| 2528 RegisterAllocationScope register_scope(this); | |
| 2529 SuperCallReference* super = expr->expression()->AsSuperCallReference(); | |
| 2530 DCHECK_NOT_NULL(super); | |
|
rmcilroy
2016/02/11 15:25:49
I don't think this DCHECK is necessary (it will cr
oth
2016/02/12 14:12:53
Done.
| |
| 2531 | |
| 2532 // Prepare the constructor to the super call. | |
| 2533 Register constructor = register_allocator()->NewRegister(); | |
| 2534 Register this_function = constructor; | |
|
rmcilroy
2016/02/11 15:25:49
Could you move this down below the CallRuntime wit
oth
2016/02/12 14:12:53
Done.
| |
| 2535 VisitForAccumulatorValue(super->this_function_var()); | |
| 2536 builder() | |
| 2537 ->StoreAccumulatorInRegister(this_function) | |
| 2538 .CallRuntime(Runtime::kInlineGetSuperConstructor, this_function, 1) | |
| 2539 .StoreAccumulatorInRegister(constructor); | |
| 2540 | |
| 2541 ZoneList<Expression*>* args = expr->arguments(); | |
| 2542 Register first_arg = VisitArguments(args); | |
| 2543 | |
| 2544 // The new target is loaded into the accumulator from the | |
| 2545 // {new.target} variable. | |
| 2546 VisitForAccumulatorValue(super->new_target_var()); | |
| 2547 | |
| 2548 // Call construct. | |
| 2549 builder()->SetExpressionPosition(expr); | |
| 2550 builder()->New(constructor, first_arg, args->length()); | |
| 2551 execution_result()->SetResultInAccumulator(); | |
| 2552 } | |
| 2277 | 2553 |
| 2278 void BytecodeGenerator::VisitCallNew(CallNew* expr) { | 2554 void BytecodeGenerator::VisitCallNew(CallNew* expr) { |
| 2279 Register constructor = register_allocator()->NewRegister(); | 2555 Register constructor = register_allocator()->NewRegister(); |
| 2280 VisitForAccumulatorValue(expr->expression()); | 2556 VisitForAccumulatorValue(expr->expression()); |
| 2281 builder()->StoreAccumulatorInRegister(constructor); | 2557 builder()->StoreAccumulatorInRegister(constructor); |
| 2282 | 2558 |
| 2283 ZoneList<Expression*>* args = expr->arguments(); | 2559 ZoneList<Expression*>* args = expr->arguments(); |
| 2284 Register first_arg = VisitArguments(args); | 2560 Register first_arg = VisitArguments(args); |
| 2561 | |
| 2285 builder()->SetExpressionPosition(expr); | 2562 builder()->SetExpressionPosition(expr); |
| 2286 builder()->New(constructor, first_arg, args->length()); | 2563 // The accumulator holds new target which is the same as the |
| 2564 // constructor for CallNew. | |
| 2565 builder() | |
| 2566 ->LoadAccumulatorWithRegister(constructor) | |
| 2567 .New(constructor, first_arg, args->length()); | |
| 2287 execution_result()->SetResultInAccumulator(); | 2568 execution_result()->SetResultInAccumulator(); |
| 2288 } | 2569 } |
| 2289 | 2570 |
| 2290 | 2571 |
| 2291 void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 2572 void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
| 2292 ZoneList<Expression*>* args = expr->arguments(); | 2573 ZoneList<Expression*>* args = expr->arguments(); |
| 2293 if (expr->is_jsruntime()) { | 2574 if (expr->is_jsruntime()) { |
| 2294 // Allocate a register for the receiver and load it with undefined. | 2575 // Allocate a register for the receiver and load it with undefined. |
| 2295 register_allocator()->PrepareForConsecutiveAllocations(1 + args->length()); | 2576 register_allocator()->PrepareForConsecutiveAllocations(1 + args->length()); |
| 2296 Register receiver = register_allocator()->NextConsecutiveRegister(); | 2577 Register receiver = register_allocator()->NextConsecutiveRegister(); |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2426 DCHECK(expr->expression()->IsValidReferenceExpressionOrThis()); | 2707 DCHECK(expr->expression()->IsValidReferenceExpressionOrThis()); |
| 2427 | 2708 |
| 2428 // Left-hand side can only be a property, a global or a variable slot. | 2709 // Left-hand side can only be a property, a global or a variable slot. |
| 2429 Property* property = expr->expression()->AsProperty(); | 2710 Property* property = expr->expression()->AsProperty(); |
| 2430 LhsKind assign_type = Property::GetAssignType(property); | 2711 LhsKind assign_type = Property::GetAssignType(property); |
| 2431 | 2712 |
| 2432 // TODO(rmcilroy): Set is_postfix to false if visiting for effect. | 2713 // TODO(rmcilroy): Set is_postfix to false if visiting for effect. |
| 2433 bool is_postfix = expr->is_postfix(); | 2714 bool is_postfix = expr->is_postfix(); |
| 2434 | 2715 |
| 2435 // Evaluate LHS expression and get old value. | 2716 // Evaluate LHS expression and get old value. |
| 2436 Register obj, key, old_value; | 2717 Register object, home_object, key, old_value; |
| 2437 Handle<String> name; | 2718 Handle<String> name; |
| 2438 switch (assign_type) { | 2719 switch (assign_type) { |
| 2439 case VARIABLE: { | 2720 case VARIABLE: { |
| 2440 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 2721 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
| 2441 VisitVariableLoadForAccumulatorValue(proxy->var(), | 2722 VisitVariableLoadForAccumulatorValue(proxy->var(), |
| 2442 proxy->VariableFeedbackSlot()); | 2723 proxy->VariableFeedbackSlot()); |
| 2443 break; | 2724 break; |
| 2444 } | 2725 } |
| 2445 case NAMED_PROPERTY: { | 2726 case NAMED_PROPERTY: { |
| 2446 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); | 2727 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); |
| 2447 obj = VisitForRegisterValue(property->obj()); | 2728 object = VisitForRegisterValue(property->obj()); |
| 2448 name = property->key()->AsLiteral()->AsPropertyName(); | 2729 name = property->key()->AsLiteral()->AsPropertyName(); |
| 2449 builder()->LoadNamedProperty(obj, name, feedback_index(slot), | 2730 builder()->LoadNamedProperty(object, name, feedback_index(slot), |
| 2450 language_mode()); | 2731 language_mode()); |
| 2451 break; | 2732 break; |
| 2452 } | 2733 } |
| 2453 case KEYED_PROPERTY: { | 2734 case KEYED_PROPERTY: { |
| 2454 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); | 2735 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); |
| 2455 obj = VisitForRegisterValue(property->obj()); | 2736 object = VisitForRegisterValue(property->obj()); |
| 2456 // Use visit for accumulator here since we need the key in the accumulator | 2737 // Use visit for accumulator here since we need the key in the accumulator |
| 2457 // for the LoadKeyedProperty. | 2738 // for the LoadKeyedProperty. |
| 2458 key = register_allocator()->NewRegister(); | 2739 key = register_allocator()->NewRegister(); |
| 2459 VisitForAccumulatorValue(property->key()); | 2740 VisitForAccumulatorValue(property->key()); |
| 2460 builder()->StoreAccumulatorInRegister(key).LoadKeyedProperty( | 2741 builder()->StoreAccumulatorInRegister(key).LoadKeyedProperty( |
| 2461 obj, feedback_index(slot), language_mode()); | 2742 object, feedback_index(slot), language_mode()); |
| 2462 break; | 2743 break; |
| 2463 } | 2744 } |
| 2464 case NAMED_SUPER_PROPERTY: | 2745 case NAMED_SUPER_PROPERTY: { |
| 2465 case KEYED_SUPER_PROPERTY: | 2746 object = VisitForRegisterValue( |
| 2466 UNIMPLEMENTED(); | 2747 property->obj()->AsSuperPropertyReference()->this_var()); |
| 2748 home_object = VisitForRegisterValue( | |
| 2749 property->obj()->AsSuperPropertyReference()->home_object()); | |
| 2750 name = property->key()->AsLiteral()->AsPropertyName(); | |
| 2751 BuildNamedSuperLoad(object, home_object, name); | |
| 2752 break; | |
| 2753 } | |
| 2754 case KEYED_SUPER_PROPERTY: { | |
| 2755 object = VisitForRegisterValue( | |
| 2756 property->obj()->AsSuperPropertyReference()->this_var()); | |
| 2757 home_object = VisitForRegisterValue( | |
| 2758 property->obj()->AsSuperPropertyReference()->home_object()); | |
| 2759 key = VisitForRegisterValue(property->key()); | |
| 2760 BuildKeyedSuperLoad(object, home_object, key); | |
| 2761 break; | |
| 2762 } | |
| 2467 } | 2763 } |
| 2468 | 2764 |
| 2469 // Convert old value into a number. | 2765 // Convert old value into a number. |
| 2470 if (!is_strong(language_mode())) { | 2766 if (!is_strong(language_mode())) { |
| 2471 builder()->CastAccumulatorToNumber(); | 2767 builder()->CastAccumulatorToNumber(); |
| 2472 } | 2768 } |
| 2473 | 2769 |
| 2474 // Save result for postfix expressions. | 2770 // Save result for postfix expressions. |
| 2475 if (is_postfix) { | 2771 if (is_postfix) { |
| 2476 old_value = register_allocator()->outer()->NewRegister(); | 2772 old_value = register_allocator()->outer()->NewRegister(); |
| 2477 builder()->StoreAccumulatorInRegister(old_value); | 2773 builder()->StoreAccumulatorInRegister(old_value); |
| 2478 } | 2774 } |
| 2479 | 2775 |
| 2480 // Perform +1/-1 operation. | 2776 // Perform +1/-1 operation. |
| 2481 builder()->CountOperation(expr->binary_op(), language_mode_strength()); | 2777 builder()->CountOperation(expr->binary_op(), language_mode_strength()); |
| 2482 | 2778 |
| 2483 // Store the value. | 2779 // Store the value. |
| 2484 FeedbackVectorSlot feedback_slot = expr->CountSlot(); | 2780 FeedbackVectorSlot feedback_slot = expr->CountSlot(); |
| 2485 switch (assign_type) { | 2781 switch (assign_type) { |
| 2486 case VARIABLE: { | 2782 case VARIABLE: { |
| 2487 Variable* variable = expr->expression()->AsVariableProxy()->var(); | 2783 Variable* variable = expr->expression()->AsVariableProxy()->var(); |
| 2488 VisitVariableAssignment(variable, expr->op(), feedback_slot); | 2784 VisitVariableAssignment(variable, expr->op(), feedback_slot); |
| 2489 break; | 2785 break; |
| 2490 } | 2786 } |
| 2491 case NAMED_PROPERTY: { | 2787 case NAMED_PROPERTY: { |
| 2492 builder()->StoreNamedProperty(obj, name, feedback_index(feedback_slot), | 2788 builder()->StoreNamedProperty(object, name, feedback_index(feedback_slot), |
| 2493 language_mode()); | 2789 language_mode()); |
| 2494 break; | 2790 break; |
| 2495 } | 2791 } |
| 2496 case KEYED_PROPERTY: { | 2792 case KEYED_PROPERTY: { |
| 2497 builder()->StoreKeyedProperty(obj, key, feedback_index(feedback_slot), | 2793 builder()->StoreKeyedProperty(object, key, feedback_index(feedback_slot), |
| 2498 language_mode()); | 2794 language_mode()); |
| 2499 break; | 2795 break; |
| 2500 } | 2796 } |
| 2501 case NAMED_SUPER_PROPERTY: | 2797 case NAMED_SUPER_PROPERTY: { |
| 2502 case KEYED_SUPER_PROPERTY: | 2798 BuildNamedSuperStore(object, home_object, name); |
| 2503 UNIMPLEMENTED(); | 2799 break; |
| 2800 } | |
| 2801 case KEYED_SUPER_PROPERTY: { | |
| 2802 BuildKeyedSuperStore(object, home_object, key); | |
| 2803 break; | |
| 2804 } | |
| 2504 } | 2805 } |
| 2505 | 2806 |
| 2506 // Restore old value for postfix expressions. | 2807 // Restore old value for postfix expressions. |
| 2507 if (is_postfix) { | 2808 if (is_postfix) { |
| 2508 execution_result()->SetResultInRegister(old_value); | 2809 execution_result()->SetResultInRegister(old_value); |
| 2509 } else { | 2810 } else { |
| 2510 execution_result()->SetResultInAccumulator(); | 2811 execution_result()->SetResultInAccumulator(); |
| 2511 } | 2812 } |
| 2512 } | 2813 } |
| 2513 | 2814 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2553 UNREACHABLE(); | 2854 UNREACHABLE(); |
| 2554 } | 2855 } |
| 2555 | 2856 |
| 2556 | 2857 |
| 2557 void BytecodeGenerator::VisitThisFunction(ThisFunction* expr) { | 2858 void BytecodeGenerator::VisitThisFunction(ThisFunction* expr) { |
| 2558 execution_result()->SetResultInRegister(Register::function_closure()); | 2859 execution_result()->SetResultInRegister(Register::function_closure()); |
| 2559 } | 2860 } |
| 2560 | 2861 |
| 2561 | 2862 |
| 2562 void BytecodeGenerator::VisitSuperCallReference(SuperCallReference* expr) { | 2863 void BytecodeGenerator::VisitSuperCallReference(SuperCallReference* expr) { |
| 2563 UNIMPLEMENTED(); | 2864 // Handled by VisitCall(). |
| 2865 UNREACHABLE(); | |
| 2564 } | 2866 } |
| 2565 | 2867 |
| 2566 | 2868 |
| 2567 void BytecodeGenerator::VisitSuperPropertyReference( | 2869 void BytecodeGenerator::VisitSuperPropertyReference( |
| 2568 SuperPropertyReference* expr) { | 2870 SuperPropertyReference* expr) { |
| 2569 UNIMPLEMENTED(); | 2871 builder()->CallRuntime(Runtime::kThrowUnsupportedSuperError, Register(0), 0); |
| 2872 execution_result()->SetResultInAccumulator(); | |
| 2570 } | 2873 } |
| 2571 | 2874 |
| 2572 | 2875 |
| 2573 void BytecodeGenerator::VisitCommaExpression(BinaryOperation* binop) { | 2876 void BytecodeGenerator::VisitCommaExpression(BinaryOperation* binop) { |
| 2574 VisitForEffect(binop->left()); | 2877 VisitForEffect(binop->left()); |
| 2575 Visit(binop->right()); | 2878 Visit(binop->right()); |
| 2576 } | 2879 } |
| 2577 | 2880 |
| 2578 | 2881 |
| 2579 void BytecodeGenerator::VisitLogicalOrExpression(BinaryOperation* binop) { | 2882 void BytecodeGenerator::VisitLogicalOrExpression(BinaryOperation* binop) { |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2732 // TODO(rmcilroy): Replace value_out with VisitForRegister(); | 3035 // TODO(rmcilroy): Replace value_out with VisitForRegister(); |
| 2733 if (property == nullptr) { | 3036 if (property == nullptr) { |
| 2734 builder()->LoadNull().StoreAccumulatorInRegister(value_out); | 3037 builder()->LoadNull().StoreAccumulatorInRegister(value_out); |
| 2735 } else { | 3038 } else { |
| 2736 VisitForAccumulatorValue(property->value()); | 3039 VisitForAccumulatorValue(property->value()); |
| 2737 builder()->StoreAccumulatorInRegister(value_out); | 3040 builder()->StoreAccumulatorInRegister(value_out); |
| 2738 VisitSetHomeObject(value_out, home_object, property); | 3041 VisitSetHomeObject(value_out, home_object, property); |
| 2739 } | 3042 } |
| 2740 } | 3043 } |
| 2741 | 3044 |
| 2742 | |
| 2743 void BytecodeGenerator::VisitSetHomeObject(Register value, Register home_object, | 3045 void BytecodeGenerator::VisitSetHomeObject(Register value, Register home_object, |
| 2744 ObjectLiteralProperty* property, | 3046 ObjectLiteralProperty* property, |
| 2745 int slot_number) { | 3047 int slot_number) { |
| 2746 Expression* expr = property->value(); | 3048 Expression* expr = property->value(); |
| 2747 if (!FunctionLiteral::NeedsHomeObject(expr)) return; | 3049 if (FunctionLiteral::NeedsHomeObject(expr)) { |
| 2748 | 3050 Handle<Name> name = isolate()->factory()->home_object_symbol(); |
| 2749 UNIMPLEMENTED(); | 3051 FeedbackVectorSlot slot = property->GetSlot(slot_number); |
| 3052 builder() | |
| 3053 ->LoadAccumulatorWithRegister(home_object) | |
| 3054 .StoreNamedProperty(value, name, feedback_index(slot), language_mode()); | |
| 3055 } | |
| 2750 } | 3056 } |
| 2751 | 3057 |
| 2752 | 3058 |
| 2753 void BytecodeGenerator::VisitArgumentsObject(Variable* variable) { | 3059 void BytecodeGenerator::VisitArgumentsObject(Variable* variable) { |
| 2754 if (variable == nullptr) return; | 3060 if (variable == nullptr) return; |
| 2755 | 3061 |
| 2756 DCHECK(variable->IsContextSlot() || variable->IsStackAllocated()); | 3062 DCHECK(variable->IsContextSlot() || variable->IsStackAllocated()); |
| 2757 | 3063 |
| 2758 // Allocate and initialize a new arguments object and assign to the | 3064 // Allocate and initialize a new arguments object and assign to the |
| 2759 // {arguments} variable. | 3065 // {arguments} variable. |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 2772 // Allocate and initialize a new rest parameter and assign to the {rest} | 3078 // Allocate and initialize a new rest parameter and assign to the {rest} |
| 2773 // variable. | 3079 // variable. |
| 2774 builder()->CreateArguments(CreateArgumentsType::kRestParameter); | 3080 builder()->CreateArguments(CreateArgumentsType::kRestParameter); |
| 2775 DCHECK(rest->IsContextSlot() || rest->IsStackAllocated()); | 3081 DCHECK(rest->IsContextSlot() || rest->IsStackAllocated()); |
| 2776 VisitVariableAssignment(rest, Token::ASSIGN, FeedbackVectorSlot::Invalid()); | 3082 VisitVariableAssignment(rest, Token::ASSIGN, FeedbackVectorSlot::Invalid()); |
| 2777 } | 3083 } |
| 2778 | 3084 |
| 2779 void BytecodeGenerator::VisitThisFunctionVariable(Variable* variable) { | 3085 void BytecodeGenerator::VisitThisFunctionVariable(Variable* variable) { |
| 2780 if (variable == nullptr) return; | 3086 if (variable == nullptr) return; |
| 2781 | 3087 |
| 2782 // TODO(rmcilroy): Remove once we have tests which exercise this code path. | |
| 2783 UNIMPLEMENTED(); | |
| 2784 | |
| 2785 // Store the closure we were called with in the given variable. | 3088 // Store the closure we were called with in the given variable. |
| 2786 builder()->LoadAccumulatorWithRegister(Register::function_closure()); | 3089 builder()->LoadAccumulatorWithRegister(Register::function_closure()); |
| 2787 VisitVariableAssignment(variable, Token::INIT, FeedbackVectorSlot::Invalid()); | 3090 VisitVariableAssignment(variable, Token::INIT, FeedbackVectorSlot::Invalid()); |
| 2788 } | 3091 } |
| 2789 | 3092 |
| 2790 | 3093 |
| 2791 void BytecodeGenerator::VisitNewTargetVariable(Variable* variable) { | 3094 void BytecodeGenerator::VisitNewTargetVariable(Variable* variable) { |
| 2792 if (variable == nullptr) return; | 3095 if (variable == nullptr) return; |
| 2793 | 3096 |
| 2794 // Store the new target we were called with in the given variable. | 3097 // 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... | |
| 2871 } | 3174 } |
| 2872 | 3175 |
| 2873 | 3176 |
| 2874 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 3177 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
| 2875 return info()->feedback_vector()->GetIndex(slot); | 3178 return info()->feedback_vector()->GetIndex(slot); |
| 2876 } | 3179 } |
| 2877 | 3180 |
| 2878 } // namespace interpreter | 3181 } // namespace interpreter |
| 2879 } // namespace internal | 3182 } // namespace internal |
| 2880 } // namespace v8 | 3183 } // namespace v8 |
| OLD | NEW |