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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/execution.h" | 7 #include "src/execution.h" |
8 #include "src/handles.h" | 8 #include "src/handles.h" |
9 #include "src/interpreter/bytecode-array-builder.h" | 9 #include "src/interpreter/bytecode-array-builder.h" |
10 #include "src/interpreter/interpreter.h" | 10 #include "src/interpreter/interpreter.h" |
(...skipping 1273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1284 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 1284 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
1285 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 1285 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
1286 auto callable = tester.GetCallable<>(); | 1286 auto callable = tester.GetCallable<>(); |
1287 Handle<Object> return_value = callable().ToHandleChecked(); | 1287 Handle<Object> return_value = callable().ToHandleChecked(); |
1288 CHECK(return_value->IsBoolean()); | 1288 CHECK(return_value->IsBoolean()); |
1289 CHECK_EQ(return_value->BooleanValue(), expected_value); | 1289 CHECK_EQ(return_value->BooleanValue(), expected_value); |
1290 } | 1290 } |
1291 } | 1291 } |
1292 | 1292 |
1293 | 1293 |
| 1294 TEST(InterpreterUnaryNot) { |
| 1295 HandleAndZoneScope handles; |
| 1296 for (size_t i = 1; i < 10; i++) { |
| 1297 bool expected_value = ((i & 1) == 1); |
| 1298 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone()); |
| 1299 Register r0(0); |
| 1300 builder.set_locals_count(0); |
| 1301 builder.set_parameter_count(0); |
| 1302 builder.EnterBlock(); |
| 1303 builder.LoadFalse(); |
| 1304 for (size_t j = 0; j < i; j++) { |
| 1305 builder.LogicalNot(); |
| 1306 } |
| 1307 builder.LeaveBlock().Return(); |
| 1308 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 1309 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 1310 auto callable = tester.GetCallable<>(); |
| 1311 Handle<Object> return_value = callable().ToHandleChecked(); |
| 1312 CHECK(return_value->IsBoolean()); |
| 1313 CHECK_EQ(return_value->BooleanValue(), expected_value); |
| 1314 } |
| 1315 } |
| 1316 |
| 1317 |
| 1318 static void LoadAny(BytecodeArrayBuilder* builder, |
| 1319 v8::internal::Factory* factory, Handle<Object> obj) { |
| 1320 if (obj->IsOddball()) { |
| 1321 if (obj->SameValue(*factory->true_value())) { |
| 1322 builder->LoadTrue(); |
| 1323 } else if (obj->SameValue(*factory->false_value())) { |
| 1324 builder->LoadFalse(); |
| 1325 } else if (obj->SameValue(*factory->the_hole_value())) { |
| 1326 builder->LoadTheHole(); |
| 1327 } else if (obj->SameValue(*factory->null_value())) { |
| 1328 builder->LoadNull(); |
| 1329 } else if (obj->SameValue(*factory->undefined_value())) { |
| 1330 builder->LoadUndefined(); |
| 1331 } else { |
| 1332 UNREACHABLE(); |
| 1333 } |
| 1334 } else if (obj->IsSmi()) { |
| 1335 builder->LoadLiteral(*Handle<Smi>::cast(obj)); |
| 1336 } else { |
| 1337 builder->LoadLiteral(obj); |
| 1338 } |
| 1339 } |
| 1340 |
| 1341 |
| 1342 TEST(InterpreterToBoolean) { |
| 1343 HandleAndZoneScope handles; |
| 1344 i::Factory* factory = handles.main_isolate()->factory(); |
| 1345 |
| 1346 std::pair<Handle<Object>, bool> object_type_tuples[] = { |
| 1347 std::make_pair(factory->undefined_value(), false), |
| 1348 std::make_pair(factory->null_value(), false), |
| 1349 std::make_pair(factory->false_value(), false), |
| 1350 std::make_pair(factory->true_value(), true), |
| 1351 std::make_pair(factory->NewNumber(9.1), true), |
| 1352 std::make_pair(factory->NewNumberFromInt(0), false), |
| 1353 std::make_pair( |
| 1354 Handle<Object>::cast(factory->NewStringFromStaticChars("hello")), |
| 1355 true), |
| 1356 std::make_pair( |
| 1357 Handle<Object>::cast(factory->NewStringFromStaticChars("")), false), |
| 1358 }; |
| 1359 |
| 1360 for (size_t i = 0; i < arraysize(object_type_tuples); i++) { |
| 1361 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone()); |
| 1362 Register r0(0); |
| 1363 builder.set_locals_count(0); |
| 1364 builder.set_parameter_count(0); |
| 1365 builder.EnterBlock(); |
| 1366 LoadAny(&builder, factory, object_type_tuples[i].first); |
| 1367 builder.CastAccumulatorToBoolean(); |
| 1368 builder.LeaveBlock().Return(); |
| 1369 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 1370 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 1371 auto callable = tester.GetCallable<>(); |
| 1372 Handle<Object> return_value = callable().ToHandleChecked(); |
| 1373 CHECK(return_value->IsBoolean()); |
| 1374 CHECK_EQ(return_value->BooleanValue(), object_type_tuples[i].second); |
| 1375 } |
| 1376 } |
| 1377 |
| 1378 |
| 1379 TEST(InterpreterUnaryNotNonBoolean) { |
| 1380 HandleAndZoneScope handles; |
| 1381 i::Factory* factory = handles.main_isolate()->factory(); |
| 1382 |
| 1383 std::pair<Handle<Object>, bool> object_type_tuples[] = { |
| 1384 std::make_pair(factory->undefined_value(), true), |
| 1385 std::make_pair(factory->null_value(), true), |
| 1386 std::make_pair(factory->false_value(), true), |
| 1387 std::make_pair(factory->true_value(), false), |
| 1388 std::make_pair(factory->NewNumber(9.1), false), |
| 1389 std::make_pair(factory->NewNumberFromInt(0), true), |
| 1390 std::make_pair( |
| 1391 Handle<Object>::cast(factory->NewStringFromStaticChars("hello")), |
| 1392 false), |
| 1393 std::make_pair( |
| 1394 Handle<Object>::cast(factory->NewStringFromStaticChars("")), true), |
| 1395 }; |
| 1396 |
| 1397 for (size_t i = 0; i < arraysize(object_type_tuples); i++) { |
| 1398 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone()); |
| 1399 Register r0(0); |
| 1400 builder.set_locals_count(0); |
| 1401 builder.set_parameter_count(0); |
| 1402 builder.EnterBlock(); |
| 1403 LoadAny(&builder, factory, object_type_tuples[i].first); |
| 1404 builder.LogicalNot(); |
| 1405 builder.LeaveBlock().Return(); |
| 1406 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 1407 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 1408 auto callable = tester.GetCallable<>(); |
| 1409 Handle<Object> return_value = callable().ToHandleChecked(); |
| 1410 CHECK(return_value->IsBoolean()); |
| 1411 CHECK_EQ(return_value->BooleanValue(), object_type_tuples[i].second); |
| 1412 } |
| 1413 } |
| 1414 |
| 1415 |
| 1416 TEST(InterpreterTypeOf) { |
| 1417 HandleAndZoneScope handles; |
| 1418 i::Factory* factory = handles.main_isolate()->factory(); |
| 1419 |
| 1420 std::pair<Handle<Object>, const char*> object_type_tuples[] = { |
| 1421 std::make_pair(factory->undefined_value(), "undefined"), |
| 1422 std::make_pair(factory->null_value(), "object"), |
| 1423 std::make_pair(factory->true_value(), "boolean"), |
| 1424 std::make_pair(factory->false_value(), "boolean"), |
| 1425 std::make_pair(factory->NewNumber(9.1), "number"), |
| 1426 std::make_pair(factory->NewNumberFromInt(7771), "number"), |
| 1427 std::make_pair( |
| 1428 Handle<Object>::cast(factory->NewStringFromStaticChars("hello")), |
| 1429 "string"), |
| 1430 }; |
| 1431 |
| 1432 for (size_t i = 0; i < arraysize(object_type_tuples); i++) { |
| 1433 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone()); |
| 1434 Register r0(0); |
| 1435 builder.set_locals_count(0); |
| 1436 builder.set_parameter_count(0); |
| 1437 builder.EnterBlock(); |
| 1438 LoadAny(&builder, factory, object_type_tuples[i].first); |
| 1439 builder.TypeOf(); |
| 1440 builder.LeaveBlock().Return(); |
| 1441 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 1442 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 1443 auto callable = tester.GetCallable<>(); |
| 1444 Handle<v8::internal::String> return_value = |
| 1445 Handle<v8::internal::String>::cast(callable().ToHandleChecked()); |
| 1446 auto actual = return_value->ToCString(); |
| 1447 CHECK_EQ(strcmp(&actual[0], object_type_tuples[i].second), 0); |
| 1448 } |
| 1449 } |
| 1450 |
| 1451 |
1294 TEST(InterpreterCallRuntime) { | 1452 TEST(InterpreterCallRuntime) { |
1295 HandleAndZoneScope handles; | 1453 HandleAndZoneScope handles; |
1296 | 1454 |
1297 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone()); | 1455 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone()); |
1298 builder.set_locals_count(2); | 1456 builder.set_locals_count(2); |
1299 builder.set_parameter_count(1); | 1457 builder.set_parameter_count(1); |
1300 builder.LoadLiteral(Smi::FromInt(15)) | 1458 builder.LoadLiteral(Smi::FromInt(15)) |
1301 .StoreAccumulatorInRegister(Register(0)) | 1459 .StoreAccumulatorInRegister(Register(0)) |
1302 .LoadLiteral(Smi::FromInt(40)) | 1460 .LoadLiteral(Smi::FromInt(40)) |
1303 .StoreAccumulatorInRegister(Register(1)) | 1461 .StoreAccumulatorInRegister(Register(1)) |
1304 .CallRuntime(Runtime::kAdd, Register(0), 2) | 1462 .CallRuntime(Runtime::kAdd, Register(0), 2) |
1305 .Return(); | 1463 .Return(); |
1306 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 1464 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
1307 | 1465 |
1308 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 1466 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
1309 auto callable = tester.GetCallable<>(); | 1467 auto callable = tester.GetCallable<>(); |
1310 | 1468 |
1311 Handle<Object> return_val = callable().ToHandleChecked(); | 1469 Handle<Object> return_val = callable().ToHandleChecked(); |
1312 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(55)); | 1470 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(55)); |
1313 } | 1471 } |
OLD | NEW |