| 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 <tuple> | 5 #include <tuple> |
| 6 | 6 |
| 7 #include "src/v8.h" | 7 #include "src/v8.h" |
| 8 | 8 |
| 9 #include "src/execution.h" | 9 #include "src/execution.h" |
| 10 #include "src/handles.h" | 10 #include "src/handles.h" |
| (...skipping 1218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1229 int slot_index = vector->GetIndex(slot); | 1229 int slot_index = vector->GetIndex(slot); |
| 1230 int call_slot_index = -1; | 1230 int call_slot_index = -1; |
| 1231 call_slot_index = vector->GetIndex(call_slot); | 1231 call_slot_index = vector->GetIndex(call_slot); |
| 1232 | 1232 |
| 1233 Handle<i::String> name = factory->NewStringFromAsciiChecked("func"); | 1233 Handle<i::String> name = factory->NewStringFromAsciiChecked("func"); |
| 1234 name = factory->string_table()->LookupString(isolate, name); | 1234 name = factory->string_table()->LookupString(isolate, name); |
| 1235 | 1235 |
| 1236 // Check with no args. | 1236 // Check with no args. |
| 1237 { | 1237 { |
| 1238 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 1); | 1238 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 1); |
| 1239 Register reg = builder.register_allocator()->NewRegister(); |
| 1240 RegisterList args = builder.register_allocator()->NewRegisterList(1); |
| 1241 builder.LoadNamedProperty(builder.Parameter(0), name, slot_index) |
| 1242 .StoreAccumulatorInRegister(reg) |
| 1243 .MoveRegister(builder.Parameter(0), args[0]); |
| 1239 | 1244 |
| 1240 builder.LoadNamedProperty(builder.Parameter(0), name, slot_index) | 1245 builder.Call(reg, args, call_slot_index, tail_call_mode); |
| 1241 .StoreAccumulatorInRegister(Register(0)); | |
| 1242 | |
| 1243 builder.Call(Register(0), builder.Parameter(0), 1, call_slot_index, | |
| 1244 tail_call_mode); | |
| 1245 | 1246 |
| 1246 builder.Return(); | 1247 builder.Return(); |
| 1247 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); | 1248 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); |
| 1248 | 1249 |
| 1249 InterpreterTester tester(isolate, bytecode_array, vector); | 1250 InterpreterTester tester(isolate, bytecode_array, vector); |
| 1250 auto callable = tester.GetCallable<Handle<Object>>(); | 1251 auto callable = tester.GetCallable<Handle<Object>>(); |
| 1251 | 1252 |
| 1252 Handle<Object> object = InterpreterTester::NewObject( | 1253 Handle<Object> object = InterpreterTester::NewObject( |
| 1253 "new (function Obj() { this.func = function() { return 0x265; }})()"); | 1254 "new (function Obj() { this.func = function() { return 0x265; }})()"); |
| 1254 Handle<Object> return_val = callable(object).ToHandleChecked(); | 1255 Handle<Object> return_val = callable(object).ToHandleChecked(); |
| 1255 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(0x265)); | 1256 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(0x265)); |
| 1256 } | 1257 } |
| 1257 | 1258 |
| 1258 // Check that receiver is passed properly. | 1259 // Check that receiver is passed properly. |
| 1259 { | 1260 { |
| 1260 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 1); | 1261 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 1); |
| 1261 | 1262 Register reg = builder.register_allocator()->NewRegister(); |
| 1263 RegisterList args = builder.register_allocator()->NewRegisterList(1); |
| 1262 builder.LoadNamedProperty(builder.Parameter(0), name, slot_index) | 1264 builder.LoadNamedProperty(builder.Parameter(0), name, slot_index) |
| 1263 .StoreAccumulatorInRegister(Register(0)); | 1265 .StoreAccumulatorInRegister(reg) |
| 1264 builder.Call(Register(0), builder.Parameter(0), 1, call_slot_index, | 1266 .MoveRegister(builder.Parameter(0), args[0]); |
| 1265 tail_call_mode); | 1267 builder.Call(reg, args, call_slot_index, tail_call_mode); |
| 1266 builder.Return(); | 1268 builder.Return(); |
| 1267 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); | 1269 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); |
| 1268 | 1270 |
| 1269 InterpreterTester tester(isolate, bytecode_array, vector); | 1271 InterpreterTester tester(isolate, bytecode_array, vector); |
| 1270 auto callable = tester.GetCallable<Handle<Object>>(); | 1272 auto callable = tester.GetCallable<Handle<Object>>(); |
| 1271 | 1273 |
| 1272 Handle<Object> object = InterpreterTester::NewObject( | 1274 Handle<Object> object = InterpreterTester::NewObject( |
| 1273 "new (function Obj() {" | 1275 "new (function Obj() {" |
| 1274 " this.val = 1234;" | 1276 " this.val = 1234;" |
| 1275 " this.func = function() { return this.val; };" | 1277 " this.func = function() { return this.val; };" |
| 1276 "})()"); | 1278 "})()"); |
| 1277 Handle<Object> return_val = callable(object).ToHandleChecked(); | 1279 Handle<Object> return_val = callable(object).ToHandleChecked(); |
| 1278 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(1234)); | 1280 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(1234)); |
| 1279 } | 1281 } |
| 1280 | 1282 |
| 1281 // Check with two parameters (+ receiver). | 1283 // Check with two parameters (+ receiver). |
| 1282 { | 1284 { |
| 1283 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 4); | 1285 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 4); |
| 1286 Register reg = builder.register_allocator()->NewRegister(); |
| 1287 RegisterList args = builder.register_allocator()->NewRegisterList(3); |
| 1284 | 1288 |
| 1285 builder.LoadNamedProperty(builder.Parameter(0), name, slot_index) | 1289 builder.LoadNamedProperty(builder.Parameter(0), name, slot_index) |
| 1286 .StoreAccumulatorInRegister(Register(0)) | 1290 .StoreAccumulatorInRegister(reg) |
| 1287 .LoadAccumulatorWithRegister(builder.Parameter(0)) | 1291 .LoadAccumulatorWithRegister(builder.Parameter(0)) |
| 1288 .StoreAccumulatorInRegister(Register(1)) | 1292 .StoreAccumulatorInRegister(args[0]) |
| 1289 .LoadLiteral(Smi::FromInt(51)) | 1293 .LoadLiteral(Smi::FromInt(51)) |
| 1290 .StoreAccumulatorInRegister(Register(2)) | 1294 .StoreAccumulatorInRegister(args[1]) |
| 1291 .LoadLiteral(Smi::FromInt(11)) | 1295 .LoadLiteral(Smi::FromInt(11)) |
| 1292 .StoreAccumulatorInRegister(Register(3)); | 1296 .StoreAccumulatorInRegister(args[2]); |
| 1293 | 1297 |
| 1294 builder.Call(Register(0), Register(1), 3, call_slot_index, tail_call_mode); | 1298 builder.Call(reg, args, call_slot_index, tail_call_mode); |
| 1295 | 1299 |
| 1296 builder.Return(); | 1300 builder.Return(); |
| 1297 | 1301 |
| 1298 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); | 1302 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); |
| 1299 | 1303 |
| 1300 InterpreterTester tester(isolate, bytecode_array, vector); | 1304 InterpreterTester tester(isolate, bytecode_array, vector); |
| 1301 auto callable = tester.GetCallable<Handle<Object>>(); | 1305 auto callable = tester.GetCallable<Handle<Object>>(); |
| 1302 | 1306 |
| 1303 Handle<Object> object = InterpreterTester::NewObject( | 1307 Handle<Object> object = InterpreterTester::NewObject( |
| 1304 "new (function Obj() { " | 1308 "new (function Obj() { " |
| 1305 " this.func = function(a, b) { return a - b; }" | 1309 " this.func = function(a, b) { return a - b; }" |
| 1306 "})()"); | 1310 "})()"); |
| 1307 Handle<Object> return_val = callable(object).ToHandleChecked(); | 1311 Handle<Object> return_val = callable(object).ToHandleChecked(); |
| 1308 CHECK(return_val->SameValue(Smi::FromInt(40))); | 1312 CHECK(return_val->SameValue(Smi::FromInt(40))); |
| 1309 } | 1313 } |
| 1310 | 1314 |
| 1311 // Check with 10 parameters (+ receiver). | 1315 // Check with 10 parameters (+ receiver). |
| 1312 { | 1316 { |
| 1313 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 12); | 1317 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 12); |
| 1318 Register reg = builder.register_allocator()->NewRegister(); |
| 1319 RegisterList args = builder.register_allocator()->NewRegisterList(11); |
| 1314 | 1320 |
| 1315 builder.LoadNamedProperty(builder.Parameter(0), name, slot_index) | 1321 builder.LoadNamedProperty(builder.Parameter(0), name, slot_index) |
| 1316 .StoreAccumulatorInRegister(Register(0)) | 1322 .StoreAccumulatorInRegister(reg) |
| 1317 .LoadAccumulatorWithRegister(builder.Parameter(0)) | 1323 .LoadAccumulatorWithRegister(builder.Parameter(0)) |
| 1318 .StoreAccumulatorInRegister(Register(1)) | 1324 .StoreAccumulatorInRegister(args[0]) |
| 1319 .LoadLiteral(factory->NewStringFromAsciiChecked("a")) | 1325 .LoadLiteral(factory->NewStringFromAsciiChecked("a")) |
| 1320 .StoreAccumulatorInRegister(Register(2)) | 1326 .StoreAccumulatorInRegister(args[1]) |
| 1321 .LoadLiteral(factory->NewStringFromAsciiChecked("b")) | 1327 .LoadLiteral(factory->NewStringFromAsciiChecked("b")) |
| 1322 .StoreAccumulatorInRegister(Register(3)) | 1328 .StoreAccumulatorInRegister(args[2]) |
| 1323 .LoadLiteral(factory->NewStringFromAsciiChecked("c")) | 1329 .LoadLiteral(factory->NewStringFromAsciiChecked("c")) |
| 1324 .StoreAccumulatorInRegister(Register(4)) | 1330 .StoreAccumulatorInRegister(args[3]) |
| 1325 .LoadLiteral(factory->NewStringFromAsciiChecked("d")) | 1331 .LoadLiteral(factory->NewStringFromAsciiChecked("d")) |
| 1326 .StoreAccumulatorInRegister(Register(5)) | 1332 .StoreAccumulatorInRegister(args[4]) |
| 1327 .LoadLiteral(factory->NewStringFromAsciiChecked("e")) | 1333 .LoadLiteral(factory->NewStringFromAsciiChecked("e")) |
| 1328 .StoreAccumulatorInRegister(Register(6)) | 1334 .StoreAccumulatorInRegister(args[5]) |
| 1329 .LoadLiteral(factory->NewStringFromAsciiChecked("f")) | 1335 .LoadLiteral(factory->NewStringFromAsciiChecked("f")) |
| 1330 .StoreAccumulatorInRegister(Register(7)) | 1336 .StoreAccumulatorInRegister(args[6]) |
| 1331 .LoadLiteral(factory->NewStringFromAsciiChecked("g")) | 1337 .LoadLiteral(factory->NewStringFromAsciiChecked("g")) |
| 1332 .StoreAccumulatorInRegister(Register(8)) | 1338 .StoreAccumulatorInRegister(args[7]) |
| 1333 .LoadLiteral(factory->NewStringFromAsciiChecked("h")) | 1339 .LoadLiteral(factory->NewStringFromAsciiChecked("h")) |
| 1334 .StoreAccumulatorInRegister(Register(9)) | 1340 .StoreAccumulatorInRegister(args[8]) |
| 1335 .LoadLiteral(factory->NewStringFromAsciiChecked("i")) | 1341 .LoadLiteral(factory->NewStringFromAsciiChecked("i")) |
| 1336 .StoreAccumulatorInRegister(Register(10)) | 1342 .StoreAccumulatorInRegister(args[9]) |
| 1337 .LoadLiteral(factory->NewStringFromAsciiChecked("j")) | 1343 .LoadLiteral(factory->NewStringFromAsciiChecked("j")) |
| 1338 .StoreAccumulatorInRegister(Register(11)); | 1344 .StoreAccumulatorInRegister(args[10]); |
| 1339 | 1345 |
| 1340 builder.Call(Register(0), Register(1), 11, call_slot_index, tail_call_mode); | 1346 builder.Call(reg, args, call_slot_index, tail_call_mode); |
| 1341 | 1347 |
| 1342 builder.Return(); | 1348 builder.Return(); |
| 1343 | 1349 |
| 1344 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); | 1350 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); |
| 1345 | 1351 |
| 1346 InterpreterTester tester(isolate, bytecode_array, vector); | 1352 InterpreterTester tester(isolate, bytecode_array, vector); |
| 1347 auto callable = tester.GetCallable<Handle<Object>>(); | 1353 auto callable = tester.GetCallable<Handle<Object>>(); |
| 1348 | 1354 |
| 1349 Handle<Object> object = InterpreterTester::NewObject( | 1355 Handle<Object> object = InterpreterTester::NewObject( |
| 1350 "new (function Obj() { " | 1356 "new (function Obj() { " |
| (...skipping 754 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2105 CHECK_EQ(strcmp(&actual[0], typeof_vals[i].second), 0); | 2111 CHECK_EQ(strcmp(&actual[0], typeof_vals[i].second), 0); |
| 2106 } | 2112 } |
| 2107 } | 2113 } |
| 2108 | 2114 |
| 2109 | 2115 |
| 2110 TEST(InterpreterCallRuntime) { | 2116 TEST(InterpreterCallRuntime) { |
| 2111 HandleAndZoneScope handles; | 2117 HandleAndZoneScope handles; |
| 2112 Isolate* isolate = handles.main_isolate(); | 2118 Isolate* isolate = handles.main_isolate(); |
| 2113 | 2119 |
| 2114 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 2); | 2120 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 2); |
| 2121 RegisterList args = builder.register_allocator()->NewRegisterList(2); |
| 2115 | 2122 |
| 2116 builder.LoadLiteral(Smi::FromInt(15)) | 2123 builder.LoadLiteral(Smi::FromInt(15)) |
| 2117 .StoreAccumulatorInRegister(Register(0)) | 2124 .StoreAccumulatorInRegister(args[0]) |
| 2118 .LoadLiteral(Smi::FromInt(40)) | 2125 .LoadLiteral(Smi::FromInt(40)) |
| 2119 .StoreAccumulatorInRegister(Register(1)) | 2126 .StoreAccumulatorInRegister(args[1]) |
| 2120 .CallRuntime(Runtime::kAdd, Register(0), 2) | 2127 .CallRuntime(Runtime::kAdd, args) |
| 2121 .Return(); | 2128 .Return(); |
| 2122 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); | 2129 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); |
| 2123 | 2130 |
| 2124 InterpreterTester tester(isolate, bytecode_array); | 2131 InterpreterTester tester(isolate, bytecode_array); |
| 2125 auto callable = tester.GetCallable<>(); | 2132 auto callable = tester.GetCallable<>(); |
| 2126 | 2133 |
| 2127 Handle<Object> return_val = callable().ToHandleChecked(); | 2134 Handle<Object> return_val = callable().ToHandleChecked(); |
| 2128 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(55)); | 2135 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(55)); |
| 2129 } | 2136 } |
| 2130 | 2137 |
| 2131 TEST(InterpreterInvokeIntrinsic) { | 2138 TEST(InterpreterInvokeIntrinsic) { |
| 2132 HandleAndZoneScope handles; | 2139 HandleAndZoneScope handles; |
| 2133 Isolate* isolate = handles.main_isolate(); | 2140 Isolate* isolate = handles.main_isolate(); |
| 2134 | 2141 |
| 2135 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 2); | 2142 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 2); |
| 2136 | 2143 |
| 2137 builder.LoadLiteral(Smi::FromInt(15)) | 2144 builder.LoadLiteral(Smi::FromInt(15)) |
| 2138 .StoreAccumulatorInRegister(Register(0)) | 2145 .StoreAccumulatorInRegister(Register(0)) |
| 2139 .CallRuntime(Runtime::kInlineIsArray, Register(0), 1) | 2146 .CallRuntime(Runtime::kInlineIsArray, Register(0)) |
| 2140 .Return(); | 2147 .Return(); |
| 2141 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); | 2148 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); |
| 2142 | 2149 |
| 2143 InterpreterTester tester(isolate, bytecode_array); | 2150 InterpreterTester tester(isolate, bytecode_array); |
| 2144 auto callable = tester.GetCallable<>(); | 2151 auto callable = tester.GetCallable<>(); |
| 2145 | 2152 |
| 2146 Handle<Object> return_val = callable().ToHandleChecked(); | 2153 Handle<Object> return_val = callable().ToHandleChecked(); |
| 2147 CHECK(return_val->IsBoolean()); | 2154 CHECK(return_val->IsBoolean()); |
| 2148 CHECK_EQ(return_val->BooleanValue(), false); | 2155 CHECK_EQ(return_val->BooleanValue(), false); |
| 2149 } | 2156 } |
| (...skipping 2655 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4805 auto callable = tester.GetCallable<>(); | 4812 auto callable = tester.GetCallable<>(); |
| 4806 | 4813 |
| 4807 Handle<i::Object> return_value = callable().ToHandleChecked(); | 4814 Handle<i::Object> return_value = callable().ToHandleChecked(); |
| 4808 CHECK(return_value->SameValue(*tests[i].second)); | 4815 CHECK(return_value->SameValue(*tests[i].second)); |
| 4809 } | 4816 } |
| 4810 } | 4817 } |
| 4811 | 4818 |
| 4812 } // namespace interpreter | 4819 } // namespace interpreter |
| 4813 } // namespace internal | 4820 } // namespace internal |
| 4814 } // namespace v8 | 4821 } // namespace v8 |
| OLD | NEW |