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/interpreter.h" | 5 #include "src/interpreter/interpreter.h" |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/compiler.h" | 8 #include "src/compiler.h" |
9 #include "src/compiler/interpreter-assembler.h" | 9 #include "src/compiler/interpreter-assembler.h" |
10 #include "src/factory.h" | 10 #include "src/factory.h" |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 // | 194 // |
195 // Store accumulator to register <dst>. | 195 // Store accumulator to register <dst>. |
196 void Interpreter::DoStar(compiler::InterpreterAssembler* assembler) { | 196 void Interpreter::DoStar(compiler::InterpreterAssembler* assembler) { |
197 Node* reg_index = __ BytecodeOperandReg(0); | 197 Node* reg_index = __ BytecodeOperandReg(0); |
198 Node* accumulator = __ GetAccumulator(); | 198 Node* accumulator = __ GetAccumulator(); |
199 __ StoreRegister(accumulator, reg_index); | 199 __ StoreRegister(accumulator, reg_index); |
200 __ Dispatch(); | 200 __ Dispatch(); |
201 } | 201 } |
202 | 202 |
203 | 203 |
204 // Exchange <reg8> <reg16> | |
205 // | |
206 // Exchange two registers. | |
207 void Interpreter::DoExchange(compiler::InterpreterAssembler* assembler) { | |
208 Node* reg0_index = __ BytecodeOperandReg(0); | |
209 Node* reg1_index = __ BytecodeOperandReg(1); | |
210 Node* reg0_value = __ LoadRegister(reg0_index); | |
211 Node* reg1_value = __ LoadRegister(reg1_index); | |
212 __ StoreRegister(reg1_value, reg0_index); | |
213 __ StoreRegister(reg0_value, reg1_index); | |
214 __ Dispatch(); | |
215 } | |
216 | |
217 | |
218 // ExchangeWide <reg16> <reg16> | |
219 // | |
220 // Exchange two registers. | |
221 void Interpreter::DoExchangeWide(compiler::InterpreterAssembler* assembler) { | |
222 return DoExchange(assembler); | |
223 } | |
224 | |
225 | |
226 // Mov <src> <dst> | 204 // Mov <src> <dst> |
227 // | 205 // |
228 // Stores the value of register <src> to register <dst>. | 206 // Stores the value of register <src> to register <dst>. |
229 void Interpreter::DoMov(compiler::InterpreterAssembler* assembler) { | 207 void Interpreter::DoMov(compiler::InterpreterAssembler* assembler) { |
230 Node* src_index = __ BytecodeOperandReg(0); | 208 Node* src_index = __ BytecodeOperandReg(0); |
231 Node* src_value = __ LoadRegister(src_index); | 209 Node* src_value = __ LoadRegister(src_index); |
232 Node* dst_index = __ BytecodeOperandReg(1); | 210 Node* dst_index = __ BytecodeOperandReg(1); |
233 __ StoreRegister(src_value, dst_index); | 211 __ StoreRegister(src_value, dst_index); |
234 __ Dispatch(); | 212 __ Dispatch(); |
235 } | 213 } |
236 | 214 |
237 | 215 |
| 216 // MovWide <src> <dst> |
| 217 // |
| 218 // Stores the value of register <src> to register <dst>. |
| 219 void Interpreter::DoMovWide(compiler::InterpreterAssembler* assembler) { |
| 220 DoMov(assembler); |
| 221 } |
| 222 |
| 223 |
238 void Interpreter::DoLoadGlobal(Callable ic, | 224 void Interpreter::DoLoadGlobal(Callable ic, |
239 compiler::InterpreterAssembler* assembler) { | 225 compiler::InterpreterAssembler* assembler) { |
240 // Get the global object. | 226 // Get the global object. |
241 Node* context = __ GetContext(); | 227 Node* context = __ GetContext(); |
242 Node* native_context = | 228 Node* native_context = |
243 __ LoadContextSlot(context, Context::NATIVE_CONTEXT_INDEX); | 229 __ LoadContextSlot(context, Context::NATIVE_CONTEXT_INDEX); |
244 Node* global = __ LoadContextSlot(native_context, Context::EXTENSION_INDEX); | 230 Node* global = __ LoadContextSlot(native_context, Context::EXTENSION_INDEX); |
245 | 231 |
246 // Load the global via the LoadIC. | 232 // Load the global via the LoadIC. |
247 Node* code_target = __ HeapConstant(ic.code()); | 233 Node* code_target = __ HeapConstant(ic.code()); |
(...skipping 833 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1081 | 1067 |
1082 // CallWide <callable> <receiver> <arg_count> | 1068 // CallWide <callable> <receiver> <arg_count> |
1083 // | 1069 // |
1084 // Call a JSfunction or Callable in |callable| with the |receiver| and | 1070 // Call a JSfunction or Callable in |callable| with the |receiver| and |
1085 // |arg_count| arguments in subsequent registers. | 1071 // |arg_count| arguments in subsequent registers. |
1086 void Interpreter::DoCallWide(compiler::InterpreterAssembler* assembler) { | 1072 void Interpreter::DoCallWide(compiler::InterpreterAssembler* assembler) { |
1087 DoJSCall(assembler); | 1073 DoJSCall(assembler); |
1088 } | 1074 } |
1089 | 1075 |
1090 | 1076 |
1091 // CallRuntime <function_id> <first_arg> <arg_count> | 1077 void Interpreter::DoCallRuntimeCommon( |
1092 // | 1078 compiler::InterpreterAssembler* assembler) { |
1093 // Call the runtime function |function_id| with the first argument in | |
1094 // register |first_arg| and |arg_count| arguments in subsequent | |
1095 // registers. | |
1096 void Interpreter::DoCallRuntime(compiler::InterpreterAssembler* assembler) { | |
1097 Node* function_id = __ BytecodeOperandIdx(0); | 1079 Node* function_id = __ BytecodeOperandIdx(0); |
1098 Node* first_arg_reg = __ BytecodeOperandReg(1); | 1080 Node* first_arg_reg = __ BytecodeOperandReg(1); |
1099 Node* first_arg = __ RegisterLocation(first_arg_reg); | 1081 Node* first_arg = __ RegisterLocation(first_arg_reg); |
1100 Node* args_count = __ BytecodeOperandCount(2); | 1082 Node* args_count = __ BytecodeOperandCount(2); |
1101 Node* result = __ CallRuntime(function_id, first_arg, args_count); | 1083 Node* result = __ CallRuntime(function_id, first_arg, args_count); |
1102 __ SetAccumulator(result); | 1084 __ SetAccumulator(result); |
1103 __ Dispatch(); | 1085 __ Dispatch(); |
1104 } | 1086 } |
1105 | 1087 |
1106 | 1088 |
1107 // CallRuntimeForPair <function_id> <first_arg> <arg_count> <first_return> | 1089 // CallRuntime <function_id> <first_arg> <arg_count> |
1108 // | 1090 // |
1109 // Call the runtime function |function_id| which returns a pair, with the | 1091 // Call the runtime function |function_id| with the first argument in |
1110 // first argument in register |first_arg| and |arg_count| arguments in | 1092 // register |first_arg| and |arg_count| arguments in subsequent |
1111 // subsequent registers. Returns the result in <first_return> and | 1093 // registers. |
1112 // <first_return + 1> | 1094 void Interpreter::DoCallRuntime(compiler::InterpreterAssembler* assembler) { |
1113 void Interpreter::DoCallRuntimeForPair( | 1095 DoCallRuntimeCommon(assembler); |
| 1096 } |
| 1097 |
| 1098 |
| 1099 // CallRuntime <function_id> <first_arg> <arg_count> |
| 1100 // |
| 1101 // Call the runtime function |function_id| with the first argument in |
| 1102 // register |first_arg| and |arg_count| arguments in subsequent |
| 1103 // registers. |
| 1104 void Interpreter::DoCallRuntimeWide(compiler::InterpreterAssembler* assembler) { |
| 1105 DoCallRuntimeCommon(assembler); |
| 1106 } |
| 1107 |
| 1108 |
| 1109 void Interpreter::DoCallRuntimeForPairCommon( |
1114 compiler::InterpreterAssembler* assembler) { | 1110 compiler::InterpreterAssembler* assembler) { |
1115 // Call the runtime function. | 1111 // Call the runtime function. |
1116 Node* function_id = __ BytecodeOperandIdx(0); | 1112 Node* function_id = __ BytecodeOperandIdx(0); |
1117 Node* first_arg_reg = __ BytecodeOperandReg(1); | 1113 Node* first_arg_reg = __ BytecodeOperandReg(1); |
1118 Node* first_arg = __ RegisterLocation(first_arg_reg); | 1114 Node* first_arg = __ RegisterLocation(first_arg_reg); |
1119 Node* args_count = __ BytecodeOperandCount(2); | 1115 Node* args_count = __ BytecodeOperandCount(2); |
1120 Node* result_pair = __ CallRuntime(function_id, first_arg, args_count, 2); | 1116 Node* result_pair = __ CallRuntime(function_id, first_arg, args_count, 2); |
1121 | 1117 |
1122 // Store the results in <first_return> and <first_return + 1> | 1118 // Store the results in <first_return> and <first_return + 1> |
1123 Node* first_return_reg = __ BytecodeOperandReg(3); | 1119 Node* first_return_reg = __ BytecodeOperandReg(3); |
1124 Node* second_return_reg = __ NextRegister(first_return_reg); | 1120 Node* second_return_reg = __ NextRegister(first_return_reg); |
1125 Node* result0 = __ Projection(0, result_pair); | 1121 Node* result0 = __ Projection(0, result_pair); |
1126 Node* result1 = __ Projection(1, result_pair); | 1122 Node* result1 = __ Projection(1, result_pair); |
1127 __ StoreRegister(result0, first_return_reg); | 1123 __ StoreRegister(result0, first_return_reg); |
1128 __ StoreRegister(result1, second_return_reg); | 1124 __ StoreRegister(result1, second_return_reg); |
1129 | |
1130 __ Dispatch(); | 1125 __ Dispatch(); |
1131 } | 1126 } |
1132 | 1127 |
1133 | 1128 |
1134 // CallJSRuntime <context_index> <receiver> <arg_count> | 1129 // CallRuntimeForPair <function_id> <first_arg> <arg_count> <first_return> |
1135 // | 1130 // |
1136 // Call the JS runtime function that has the |context_index| with the receiver | 1131 // Call the runtime function |function_id| which returns a pair, with the |
1137 // in register |receiver| and |arg_count| arguments in subsequent registers. | 1132 // first argument in register |first_arg| and |arg_count| arguments in |
1138 void Interpreter::DoCallJSRuntime(compiler::InterpreterAssembler* assembler) { | 1133 // subsequent registers. Returns the result in <first_return> and |
| 1134 // <first_return + 1> |
| 1135 void Interpreter::DoCallRuntimeForPair( |
| 1136 compiler::InterpreterAssembler* assembler) { |
| 1137 DoCallRuntimeForPairCommon(assembler); |
| 1138 } |
| 1139 |
| 1140 |
| 1141 // CallRuntimeForPairWide <function_id> <first_arg> <arg_count> <first_return> |
| 1142 // |
| 1143 // Call the runtime function |function_id| which returns a pair, with the |
| 1144 // first argument in register |first_arg| and |arg_count| arguments in |
| 1145 // subsequent registers. Returns the result in <first_return> and |
| 1146 // <first_return + 1> |
| 1147 void Interpreter::DoCallRuntimeForPairWide( |
| 1148 compiler::InterpreterAssembler* assembler) { |
| 1149 DoCallRuntimeForPairCommon(assembler); |
| 1150 } |
| 1151 |
| 1152 |
| 1153 void Interpreter::DoCallJSRuntimeCommon( |
| 1154 compiler::InterpreterAssembler* assembler) { |
1139 Node* context_index = __ BytecodeOperandIdx(0); | 1155 Node* context_index = __ BytecodeOperandIdx(0); |
1140 Node* receiver_reg = __ BytecodeOperandReg(1); | 1156 Node* receiver_reg = __ BytecodeOperandReg(1); |
1141 Node* first_arg = __ RegisterLocation(receiver_reg); | 1157 Node* first_arg = __ RegisterLocation(receiver_reg); |
1142 Node* args_count = __ BytecodeOperandCount(2); | 1158 Node* args_count = __ BytecodeOperandCount(2); |
1143 | 1159 |
1144 // Get the function to call from the native context. | 1160 // Get the function to call from the native context. |
1145 Node* context = __ GetContext(); | 1161 Node* context = __ GetContext(); |
1146 Node* native_context = | 1162 Node* native_context = |
1147 __ LoadContextSlot(context, Context::NATIVE_CONTEXT_INDEX); | 1163 __ LoadContextSlot(context, Context::NATIVE_CONTEXT_INDEX); |
1148 Node* function = __ LoadContextSlot(native_context, context_index); | 1164 Node* function = __ LoadContextSlot(native_context, context_index); |
1149 | 1165 |
1150 // Call the function. | 1166 // Call the function. |
1151 Node* result = __ CallJS(function, first_arg, args_count); | 1167 Node* result = __ CallJS(function, first_arg, args_count); |
1152 __ SetAccumulator(result); | 1168 __ SetAccumulator(result); |
1153 __ Dispatch(); | 1169 __ Dispatch(); |
1154 } | 1170 } |
1155 | 1171 |
1156 | 1172 |
1157 // New <constructor> <first_arg> <arg_count> | 1173 // CallJSRuntime <context_index> <receiver> <arg_count> |
1158 // | 1174 // |
1159 // Call operator new with |constructor| and the first argument in | 1175 // Call the JS runtime function that has the |context_index| with the receiver |
1160 // register |first_arg| and |arg_count| arguments in subsequent | 1176 // in register |receiver| and |arg_count| arguments in subsequent registers. |
| 1177 void Interpreter::DoCallJSRuntime(compiler::InterpreterAssembler* assembler) { |
| 1178 DoCallJSRuntimeCommon(assembler); |
| 1179 } |
| 1180 |
| 1181 |
| 1182 // CallJSRuntimeWide <context_index> <receiver> <arg_count> |
1161 // | 1183 // |
1162 void Interpreter::DoNew(compiler::InterpreterAssembler* assembler) { | 1184 // Call the JS runtime function that has the |context_index| with the receiver |
| 1185 // in register |receiver| and |arg_count| arguments in subsequent registers. |
| 1186 void Interpreter::DoCallJSRuntimeWide( |
| 1187 compiler::InterpreterAssembler* assembler) { |
| 1188 DoCallJSRuntimeCommon(assembler); |
| 1189 } |
| 1190 |
| 1191 |
| 1192 void Interpreter::DoCallConstruct(compiler::InterpreterAssembler* assembler) { |
1163 Callable ic = CodeFactory::InterpreterPushArgsAndConstruct(isolate_); | 1193 Callable ic = CodeFactory::InterpreterPushArgsAndConstruct(isolate_); |
1164 Node* constructor_reg = __ BytecodeOperandReg(0); | 1194 Node* constructor_reg = __ BytecodeOperandReg(0); |
1165 Node* constructor = __ LoadRegister(constructor_reg); | 1195 Node* constructor = __ LoadRegister(constructor_reg); |
1166 Node* first_arg_reg = __ BytecodeOperandReg(1); | 1196 Node* first_arg_reg = __ BytecodeOperandReg(1); |
1167 Node* first_arg = __ RegisterLocation(first_arg_reg); | 1197 Node* first_arg = __ RegisterLocation(first_arg_reg); |
1168 Node* args_count = __ BytecodeOperandCount(2); | 1198 Node* args_count = __ BytecodeOperandCount(2); |
1169 Node* result = | 1199 Node* result = |
1170 __ CallConstruct(constructor, constructor, first_arg, args_count); | 1200 __ CallConstruct(constructor, constructor, first_arg, args_count); |
1171 __ SetAccumulator(result); | 1201 __ SetAccumulator(result); |
1172 __ Dispatch(); | 1202 __ Dispatch(); |
1173 } | 1203 } |
1174 | 1204 |
1175 | 1205 |
| 1206 // New <constructor> <first_arg> <arg_count> |
| 1207 // |
| 1208 // Call operator new with |constructor| and the first argument in |
| 1209 // register |first_arg| and |arg_count| arguments in subsequent |
| 1210 // |
| 1211 void Interpreter::DoNew(compiler::InterpreterAssembler* assembler) { |
| 1212 DoCallConstruct(assembler); |
| 1213 } |
| 1214 |
| 1215 |
| 1216 // NewWide <constructor> <first_arg> <arg_count> |
| 1217 // |
| 1218 // Call operator new with |constructor| and the first argument in |
| 1219 // register |first_arg| and |arg_count| arguments in subsequent |
| 1220 // |
| 1221 void Interpreter::DoNewWide(compiler::InterpreterAssembler* assembler) { |
| 1222 DoCallConstruct(assembler); |
| 1223 } |
| 1224 |
| 1225 |
1176 // TestEqual <src> | 1226 // TestEqual <src> |
1177 // | 1227 // |
1178 // Test if the value in the <src> register equals the accumulator. | 1228 // Test if the value in the <src> register equals the accumulator. |
1179 void Interpreter::DoTestEqual(compiler::InterpreterAssembler* assembler) { | 1229 void Interpreter::DoTestEqual(compiler::InterpreterAssembler* assembler) { |
1180 DoBinaryOp(Runtime::kInterpreterEquals, assembler); | 1230 DoBinaryOp(Runtime::kInterpreterEquals, assembler); |
1181 } | 1231 } |
1182 | 1232 |
1183 | 1233 |
1184 // TestNotEqual <src> | 1234 // TestNotEqual <src> |
1185 // | 1235 // |
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1720 Node* result_triple = __ CallRuntime(Runtime::kForInPrepare, object); | 1770 Node* result_triple = __ CallRuntime(Runtime::kForInPrepare, object); |
1721 | 1771 |
1722 // Set output registers: | 1772 // Set output registers: |
1723 // 0 == cache_type, 1 == cache_array, 2 == cache_length | 1773 // 0 == cache_type, 1 == cache_array, 2 == cache_length |
1724 Node* output_register = __ BytecodeOperandReg(0); | 1774 Node* output_register = __ BytecodeOperandReg(0); |
1725 for (int i = 0; i < 3; i++) { | 1775 for (int i = 0; i < 3; i++) { |
1726 Node* cache_info = __ Projection(i, result_triple); | 1776 Node* cache_info = __ Projection(i, result_triple); |
1727 __ StoreRegister(cache_info, output_register); | 1777 __ StoreRegister(cache_info, output_register); |
1728 output_register = __ NextRegister(output_register); | 1778 output_register = __ NextRegister(output_register); |
1729 } | 1779 } |
| 1780 __ Dispatch(); |
| 1781 } |
1730 | 1782 |
1731 __ Dispatch(); | 1783 |
| 1784 // ForInPrepareWide <cache_info_triple> |
| 1785 // |
| 1786 // Returns state for for..in loop execution based on the object in the |
| 1787 // accumulator. The result is output in registers |cache_info_triple| to |
| 1788 // |cache_info_triple + 2|, with the registers holding cache_type, cache_array, |
| 1789 // and cache_length respectively. |
| 1790 void Interpreter::DoForInPrepareWide( |
| 1791 compiler::InterpreterAssembler* assembler) { |
| 1792 DoForInPrepare(assembler); |
1732 } | 1793 } |
1733 | 1794 |
1734 | 1795 |
1735 // ForInNext <receiver> <index> <cache_info_pair> | 1796 // ForInNext <receiver> <index> <cache_info_pair> |
1736 // | 1797 // |
1737 // Returns the next enumerable property in the the accumulator. | 1798 // Returns the next enumerable property in the the accumulator. |
1738 void Interpreter::DoForInNext(compiler::InterpreterAssembler* assembler) { | 1799 void Interpreter::DoForInNext(compiler::InterpreterAssembler* assembler) { |
1739 Node* receiver_reg = __ BytecodeOperandReg(0); | 1800 Node* receiver_reg = __ BytecodeOperandReg(0); |
1740 Node* receiver = __ LoadRegister(receiver_reg); | 1801 Node* receiver = __ LoadRegister(receiver_reg); |
1741 Node* index_reg = __ BytecodeOperandReg(1); | 1802 Node* index_reg = __ BytecodeOperandReg(1); |
1742 Node* index = __ LoadRegister(index_reg); | 1803 Node* index = __ LoadRegister(index_reg); |
1743 Node* cache_type_reg = __ BytecodeOperandReg(2); | 1804 Node* cache_type_reg = __ BytecodeOperandReg(2); |
1744 Node* cache_type = __ LoadRegister(cache_type_reg); | 1805 Node* cache_type = __ LoadRegister(cache_type_reg); |
1745 Node* cache_array_reg = __ NextRegister(cache_type_reg); | 1806 Node* cache_array_reg = __ NextRegister(cache_type_reg); |
1746 Node* cache_array = __ LoadRegister(cache_array_reg); | 1807 Node* cache_array = __ LoadRegister(cache_array_reg); |
1747 Node* result = __ CallRuntime(Runtime::kForInNext, receiver, cache_array, | 1808 Node* result = __ CallRuntime(Runtime::kForInNext, receiver, cache_array, |
1748 cache_type, index); | 1809 cache_type, index); |
1749 __ SetAccumulator(result); | 1810 __ SetAccumulator(result); |
1750 __ Dispatch(); | 1811 __ Dispatch(); |
1751 } | 1812 } |
1752 | 1813 |
1753 | 1814 |
| 1815 // ForInNextWide <receiver> <index> <cache_info_pair> |
| 1816 // |
| 1817 // Returns the next enumerable property in the the accumulator. |
| 1818 void Interpreter::DoForInNextWide(compiler::InterpreterAssembler* assembler) { |
| 1819 return DoForInNext(assembler); |
| 1820 } |
| 1821 |
| 1822 |
1754 // ForInDone <index> <cache_length> | 1823 // ForInDone <index> <cache_length> |
1755 // | 1824 // |
1756 // Returns true if the end of the enumerable properties has been reached. | 1825 // Returns true if the end of the enumerable properties has been reached. |
1757 void Interpreter::DoForInDone(compiler::InterpreterAssembler* assembler) { | 1826 void Interpreter::DoForInDone(compiler::InterpreterAssembler* assembler) { |
1758 // TODO(oth): Implement directly rather than making a runtime call. | 1827 // TODO(oth): Implement directly rather than making a runtime call. |
1759 Node* index_reg = __ BytecodeOperandReg(0); | 1828 Node* index_reg = __ BytecodeOperandReg(0); |
1760 Node* index = __ LoadRegister(index_reg); | 1829 Node* index = __ LoadRegister(index_reg); |
1761 Node* cache_length_reg = __ BytecodeOperandReg(1); | 1830 Node* cache_length_reg = __ BytecodeOperandReg(1); |
1762 Node* cache_length = __ LoadRegister(cache_length_reg); | 1831 Node* cache_length = __ LoadRegister(cache_length_reg); |
1763 Node* result = __ CallRuntime(Runtime::kForInDone, index, cache_length); | 1832 Node* result = __ CallRuntime(Runtime::kForInDone, index, cache_length); |
(...skipping 11 matching lines...) Expand all Loading... |
1775 Node* index_reg = __ BytecodeOperandReg(0); | 1844 Node* index_reg = __ BytecodeOperandReg(0); |
1776 Node* index = __ LoadRegister(index_reg); | 1845 Node* index = __ LoadRegister(index_reg); |
1777 Node* result = __ CallRuntime(Runtime::kForInStep, index); | 1846 Node* result = __ CallRuntime(Runtime::kForInStep, index); |
1778 __ SetAccumulator(result); | 1847 __ SetAccumulator(result); |
1779 __ Dispatch(); | 1848 __ Dispatch(); |
1780 } | 1849 } |
1781 | 1850 |
1782 } // namespace interpreter | 1851 } // namespace interpreter |
1783 } // namespace internal | 1852 } // namespace internal |
1784 } // namespace v8 | 1853 } // namespace v8 |
OLD | NEW |