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 <utility> | 5 #include <utility> |
6 | 6 |
7 #include "src/compiler/pipeline.h" | 7 #include "src/compiler/pipeline.h" |
8 #include "src/execution.h" | 8 #include "src/execution.h" |
9 #include "src/handles.h" | 9 #include "src/handles.h" |
10 #include "src/interpreter/bytecode-array-builder.h" | 10 #include "src/interpreter/bytecode-array-builder.h" |
(...skipping 1430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1441 SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName, | 1441 SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName, |
1442 snippets[i].code_snippet, kFunctionName); | 1442 snippets[i].code_snippet, kFunctionName); |
1443 | 1443 |
1444 BytecodeGraphTester tester(isolate, zone, script.start()); | 1444 BytecodeGraphTester tester(isolate, zone, script.start()); |
1445 auto callable = tester.GetCallable<>(); | 1445 auto callable = tester.GetCallable<>(); |
1446 Handle<Object> return_value = callable().ToHandleChecked(); | 1446 Handle<Object> return_value = callable().ToHandleChecked(); |
1447 CHECK(return_value->SameValue(*snippets[i].return_value())); | 1447 CHECK(return_value->SameValue(*snippets[i].return_value())); |
1448 } | 1448 } |
1449 } | 1449 } |
1450 | 1450 |
| 1451 |
| 1452 TEST(BytecodeGraphBuilderIf) { |
| 1453 HandleAndZoneScope scope; |
| 1454 Isolate* isolate = scope.main_isolate(); |
| 1455 Zone* zone = scope.main_zone(); |
| 1456 Factory* factory = isolate->factory(); |
| 1457 |
| 1458 ExpectedSnippet<1> snippets[] = { |
| 1459 {"if (p1 > 1) return 1;\n" |
| 1460 "return -1;", |
| 1461 {factory->NewNumberFromInt(1), factory->NewNumberFromInt(2)}}, |
| 1462 {"if (p1 > 1) return 1;\n" |
| 1463 "return -1;", |
| 1464 {factory->NewNumberFromInt(-1), factory->NewNumberFromInt(1)}}, |
| 1465 {"if (p1 > 1) { return 1; } else { return -1; }", |
| 1466 {factory->NewNumberFromInt(1), factory->NewNumberFromInt(2)}}, |
| 1467 {"if (p1 > 1) { return 1; } else { return -1; }", |
| 1468 {factory->NewNumberFromInt(-1), factory->NewNumberFromInt(1)}}, |
| 1469 {"if (p1 > 50) {\n" |
| 1470 " return 1;\n" |
| 1471 "} else if (p1 < 10) {\n" |
| 1472 " return 10;\n" |
| 1473 "} else {\n" |
| 1474 " return -10;\n" |
| 1475 "}", |
| 1476 {factory->NewNumberFromInt(1), factory->NewNumberFromInt(51)}}, |
| 1477 {"if (p1 > 50) {\n" |
| 1478 " return 1;\n" |
| 1479 "} else if (p1 < 10) {\n" |
| 1480 " return 10;\n" |
| 1481 "} else {\n" |
| 1482 " return 100;\n" |
| 1483 "}", |
| 1484 {factory->NewNumberFromInt(10), factory->NewNumberFromInt(9)}}, |
| 1485 {"if (p1 > 50) {\n" |
| 1486 " return 1;\n" |
| 1487 "} else if (p1 < 10) {\n" |
| 1488 " return 10;\n" |
| 1489 "} else {\n" |
| 1490 " return 100;\n" |
| 1491 "}", |
| 1492 {factory->NewNumberFromInt(100), factory->NewNumberFromInt(10)}}, |
| 1493 {"if (p1 >= 0) {\n" |
| 1494 " if (p1 > 10) { return 2; } else { return 1; }\n" |
| 1495 "} else {\n" |
| 1496 " if (p1 < -10) { return -2; } else { return -1; }\n" |
| 1497 "}", |
| 1498 {factory->NewNumberFromInt(2), factory->NewNumberFromInt(100)}}, |
| 1499 {"if (p1 >= 0) {\n" |
| 1500 " if (p1 > 10) { return 2; } else { return 1; }\n" |
| 1501 "} else {\n" |
| 1502 " if (p1 < -10) { return -2; } else { return -1; }\n" |
| 1503 "}", |
| 1504 {factory->NewNumberFromInt(1), factory->NewNumberFromInt(10)}}, |
| 1505 {"if (p1 >= 0) {\n" |
| 1506 " if (p1 > 10) { return 2; } else { return 1; }\n" |
| 1507 "} else {\n" |
| 1508 " if (p1 < -10) { return -2; } else { return -1; }\n" |
| 1509 "}", |
| 1510 {factory->NewNumberFromInt(-2), factory->NewNumberFromInt(-11)}}, |
| 1511 {"if (p1 >= 0) {\n" |
| 1512 " if (p1 > 10) { return 2; } else { return 1; }\n" |
| 1513 "} else {\n" |
| 1514 " if (p1 < -10) { return -2; } else { return -1; }\n" |
| 1515 "}", |
| 1516 {factory->NewNumberFromInt(-1), factory->NewNumberFromInt(-10)}}, |
| 1517 }; |
| 1518 |
| 1519 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); |
| 1520 for (size_t i = 0; i < num_snippets; i++) { |
| 1521 ScopedVector<char> script(2048); |
| 1522 SNPrintF(script, "function %s(p1) { %s };\n%s(0);", kFunctionName, |
| 1523 snippets[i].code_snippet, kFunctionName); |
| 1524 |
| 1525 BytecodeGraphTester tester(isolate, zone, script.start()); |
| 1526 auto callable = tester.GetCallable<Handle<Object>>(); |
| 1527 Handle<Object> return_value = |
| 1528 callable(snippets[i].parameter(0)).ToHandleChecked(); |
| 1529 CHECK(return_value->SameValue(*snippets[i].return_value())); |
| 1530 } |
| 1531 } |
| 1532 |
| 1533 |
| 1534 TEST(BytecodeGraphBuilderConditionalOperator) { |
| 1535 HandleAndZoneScope scope; |
| 1536 Isolate* isolate = scope.main_isolate(); |
| 1537 Zone* zone = scope.main_zone(); |
| 1538 Factory* factory = isolate->factory(); |
| 1539 |
| 1540 ExpectedSnippet<1> snippets[] = { |
| 1541 {"return (p1 > 1) ? 1 : -1;", |
| 1542 {factory->NewNumberFromInt(1), factory->NewNumberFromInt(2)}}, |
| 1543 {"return (p1 > 1) ? 1 : -1;", |
| 1544 {factory->NewNumberFromInt(-1), factory->NewNumberFromInt(0)}}, |
| 1545 {"return (p1 > 50) ? 1 : ((p1 < 10) ? 10 : -10);", |
| 1546 {factory->NewNumberFromInt(10), factory->NewNumberFromInt(2)}}, |
| 1547 {"return (p1 > 50) ? 1 : ((p1 < 10) ? 10 : -10);", |
| 1548 {factory->NewNumberFromInt(-10), factory->NewNumberFromInt(20)}}, |
| 1549 }; |
| 1550 |
| 1551 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); |
| 1552 for (size_t i = 0; i < num_snippets; i++) { |
| 1553 ScopedVector<char> script(2048); |
| 1554 SNPrintF(script, "function %s(p1) { %s };\n%s(0);", kFunctionName, |
| 1555 snippets[i].code_snippet, kFunctionName); |
| 1556 |
| 1557 BytecodeGraphTester tester(isolate, zone, script.start()); |
| 1558 auto callable = tester.GetCallable<Handle<Object>>(); |
| 1559 Handle<Object> return_value = |
| 1560 callable(snippets[i].parameter(0)).ToHandleChecked(); |
| 1561 CHECK(return_value->SameValue(*snippets[i].return_value())); |
| 1562 } |
| 1563 } |
| 1564 |
| 1565 |
| 1566 TEST(BytecodeGraphBuilderSwitch) { |
| 1567 HandleAndZoneScope scope; |
| 1568 Isolate* isolate = scope.main_isolate(); |
| 1569 Zone* zone = scope.main_zone(); |
| 1570 Factory* factory = isolate->factory(); |
| 1571 |
| 1572 const char* switch_code = |
| 1573 "switch (p1) {\n" |
| 1574 " case 1: return 0;\n" |
| 1575 " case 2: return 1;\n" |
| 1576 " case 3:\n" |
| 1577 " case 4: return 2;\n" |
| 1578 " case 9: break;\n" |
| 1579 " default: return 3;\n" |
| 1580 "}\n" |
| 1581 "return 9;"; |
| 1582 |
| 1583 ExpectedSnippet<1> snippets[] = { |
| 1584 {switch_code, |
| 1585 {factory->NewNumberFromInt(0), factory->NewNumberFromInt(1)}}, |
| 1586 {switch_code, |
| 1587 {factory->NewNumberFromInt(1), factory->NewNumberFromInt(2)}}, |
| 1588 {switch_code, |
| 1589 {factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}}, |
| 1590 {switch_code, |
| 1591 {factory->NewNumberFromInt(2), factory->NewNumberFromInt(4)}}, |
| 1592 {switch_code, |
| 1593 {factory->NewNumberFromInt(9), factory->NewNumberFromInt(9)}}, |
| 1594 {switch_code, |
| 1595 {factory->NewNumberFromInt(3), factory->NewNumberFromInt(5)}}, |
| 1596 {switch_code, |
| 1597 {factory->NewNumberFromInt(3), factory->NewNumberFromInt(6)}}, |
| 1598 }; |
| 1599 |
| 1600 for (size_t i = 0; i < arraysize(snippets); i++) { |
| 1601 ScopedVector<char> script(2048); |
| 1602 SNPrintF(script, "function %s(p1) { %s };\n%s(0);", kFunctionName, |
| 1603 snippets[i].code_snippet, kFunctionName); |
| 1604 |
| 1605 BytecodeGraphTester tester(isolate, zone, script.start()); |
| 1606 auto callable = tester.GetCallable<Handle<Object>>(); |
| 1607 Handle<Object> return_value = |
| 1608 callable(snippets[i].parameter(0)).ToHandleChecked(); |
| 1609 CHECK(return_value->SameValue(*snippets[i].return_value())); |
| 1610 } |
| 1611 } |
| 1612 |
| 1613 |
| 1614 TEST(BytecodeGraphBuilderNestedSwitch) { |
| 1615 HandleAndZoneScope scope; |
| 1616 Isolate* isolate = scope.main_isolate(); |
| 1617 Zone* zone = scope.main_zone(); |
| 1618 Factory* factory = isolate->factory(); |
| 1619 |
| 1620 const char* switch_code = |
| 1621 "switch (p1) {\n" |
| 1622 " case 0: {" |
| 1623 " switch (p2) { case 0: return 0; case 1: return 1; case 2: break; }\n" |
| 1624 " return -1;" |
| 1625 " }\n" |
| 1626 " case 1: {" |
| 1627 " switch (p2) { case 0: return 2; case 1: return 3; }\n" |
| 1628 " }\n" |
| 1629 " case 2: break;" |
| 1630 " }\n" |
| 1631 "return -2;"; |
| 1632 |
| 1633 ExpectedSnippet<2> snippets[] = { |
| 1634 {switch_code, |
| 1635 {factory->NewNumberFromInt(0), factory->NewNumberFromInt(0), |
| 1636 factory->NewNumberFromInt(0)}}, |
| 1637 {switch_code, |
| 1638 {factory->NewNumberFromInt(1), factory->NewNumberFromInt(0), |
| 1639 factory->NewNumberFromInt(1)}}, |
| 1640 {switch_code, |
| 1641 {factory->NewNumberFromInt(-1), factory->NewNumberFromInt(0), |
| 1642 factory->NewNumberFromInt(2)}}, |
| 1643 {switch_code, |
| 1644 {factory->NewNumberFromInt(-1), factory->NewNumberFromInt(0), |
| 1645 factory->NewNumberFromInt(3)}}, |
| 1646 {switch_code, |
| 1647 {factory->NewNumberFromInt(2), factory->NewNumberFromInt(1), |
| 1648 factory->NewNumberFromInt(0)}}, |
| 1649 {switch_code, |
| 1650 {factory->NewNumberFromInt(3), factory->NewNumberFromInt(1), |
| 1651 factory->NewNumberFromInt(1)}}, |
| 1652 {switch_code, |
| 1653 {factory->NewNumberFromInt(-2), factory->NewNumberFromInt(1), |
| 1654 factory->NewNumberFromInt(2)}}, |
| 1655 {switch_code, |
| 1656 {factory->NewNumberFromInt(-2), factory->NewNumberFromInt(2), |
| 1657 factory->NewNumberFromInt(0)}}, |
| 1658 }; |
| 1659 |
| 1660 for (size_t i = 0; i < arraysize(snippets); i++) { |
| 1661 ScopedVector<char> script(2048); |
| 1662 SNPrintF(script, "function %s(p1, p2) { %s };\n%s(0, 0);", kFunctionName, |
| 1663 snippets[i].code_snippet, kFunctionName); |
| 1664 |
| 1665 BytecodeGraphTester tester(isolate, zone, script.start()); |
| 1666 auto callable = tester.GetCallable<Handle<Object>, Handle<Object>>(); |
| 1667 Handle<Object> return_value = |
| 1668 callable(snippets[i].parameter(0), snippets[i].parameter(1)) |
| 1669 .ToHandleChecked(); |
| 1670 CHECK(return_value->SameValue(*snippets[i].return_value())); |
| 1671 } |
| 1672 } |
| 1673 |
| 1674 |
| 1675 TEST(BytecodeGraphBuilderWhile) { |
| 1676 HandleAndZoneScope scope; |
| 1677 Isolate* isolate = scope.main_isolate(); |
| 1678 Zone* zone = scope.main_zone(); |
| 1679 Factory* factory = isolate->factory(); |
| 1680 |
| 1681 ExpectedSnippet<0> snippets[] = { |
| 1682 {"var x = 1; while (x < 1) { x *= 100; } return x;", |
| 1683 {factory->NewNumberFromInt(1)}}, |
| 1684 {"var x = 1, y = 0; while (x < 7) { y += x * x; x += 1; } return y;", |
| 1685 {factory->NewNumberFromInt(91)}}, |
| 1686 {"var x = 1; while (true) { x += 1; if (x == 10) break; } return x;", |
| 1687 {factory->NewNumberFromInt(10)}}, |
| 1688 {"var x = 1; while (false) { x += 1; } return x;", |
| 1689 {factory->NewNumberFromInt(1)}}, |
| 1690 {"var x = 0;\n" |
| 1691 "while (true) {\n" |
| 1692 " while (x < 10) {\n" |
| 1693 " x = x * x + 1;\n" |
| 1694 " }" |
| 1695 " x += 1;\n" |
| 1696 " break;\n" |
| 1697 "}\n" |
| 1698 "return x;", |
| 1699 {factory->NewNumberFromInt(27)}}, |
| 1700 {"var x = 1, y = 0;\n" |
| 1701 "while (x < 7) {\n" |
| 1702 " x += 1;\n" |
| 1703 " if (x == 2) continue;\n" |
| 1704 " if (x == 3) continue;\n" |
| 1705 " y += x * x;\n" |
| 1706 " if (x == 4) break;\n" |
| 1707 "}\n" |
| 1708 "return y;", |
| 1709 {factory->NewNumberFromInt(16)}}}; |
| 1710 |
| 1711 for (size_t i = 0; i < arraysize(snippets); i++) { |
| 1712 ScopedVector<char> script(1024); |
| 1713 SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName, |
| 1714 snippets[i].code_snippet, kFunctionName); |
| 1715 |
| 1716 BytecodeGraphTester tester(isolate, zone, script.start()); |
| 1717 auto callable = tester.GetCallable<>(); |
| 1718 Handle<Object> return_value = callable().ToHandleChecked(); |
| 1719 CHECK(return_value->SameValue(*snippets[i].return_value())); |
| 1720 } |
| 1721 } |
| 1722 |
| 1723 |
| 1724 TEST(BytecodeGraphBuilderDo) { |
| 1725 HandleAndZoneScope scope; |
| 1726 Isolate* isolate = scope.main_isolate(); |
| 1727 Zone* zone = scope.main_zone(); |
| 1728 Factory* factory = isolate->factory(); |
| 1729 |
| 1730 ExpectedSnippet<0> snippets[] = { |
| 1731 {"var x = 1; do { x *= 100; } while (x < 100); return x;", |
| 1732 {factory->NewNumberFromInt(100)}}, |
| 1733 {"var x = 1; do { x = x * x + 1; } while (x < 7) return x;", |
| 1734 {factory->NewNumberFromInt(26)}}, |
| 1735 {"var x = 1; do { x += 1; } while (false); return x;", |
| 1736 {factory->NewNumberFromInt(2)}}, |
| 1737 {"var x = 1, y = 0;\n" |
| 1738 "do {\n" |
| 1739 " x += 1;\n" |
| 1740 " if (x == 2) continue;\n" |
| 1741 " if (x == 3) continue;\n" |
| 1742 " y += x * x;\n" |
| 1743 " if (x == 4) break;\n" |
| 1744 "} while (x < 7);\n" |
| 1745 "return y;", |
| 1746 {factory->NewNumberFromInt(16)}}}; |
| 1747 |
| 1748 for (size_t i = 0; i < arraysize(snippets); i++) { |
| 1749 ScopedVector<char> script(1024); |
| 1750 SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName, |
| 1751 snippets[i].code_snippet, kFunctionName); |
| 1752 |
| 1753 BytecodeGraphTester tester(isolate, zone, script.start()); |
| 1754 auto callable = tester.GetCallable<>(); |
| 1755 Handle<Object> return_value = callable().ToHandleChecked(); |
| 1756 CHECK(return_value->SameValue(*snippets[i].return_value())); |
| 1757 } |
| 1758 } |
| 1759 |
| 1760 |
| 1761 TEST(BytecodeGraphBuilderFor) { |
| 1762 HandleAndZoneScope scope; |
| 1763 Isolate* isolate = scope.main_isolate(); |
| 1764 Zone* zone = scope.main_zone(); |
| 1765 Factory* factory = isolate->factory(); |
| 1766 |
| 1767 ExpectedSnippet<0> snippets[] = { |
| 1768 {"for (var x = 0;; x = 2 * x + 1) { if (x > 10) return x; }", |
| 1769 {factory->NewNumberFromInt(15)}}, |
| 1770 {"for (var x = 0; true; x = 2 * x + 1) { if (x > 100) return x; }", |
| 1771 {factory->NewNumberFromInt(127)}}, |
| 1772 {"for (var x = 0; false; x = 2 * x + 1) { if (x > 100) return x; } " |
| 1773 "return 0;", |
| 1774 {factory->NewNumberFromInt(0)}}, |
| 1775 {"for (var x = 0; x < 200; x = 2 * x + 1) { x = x; } return x;", |
| 1776 {factory->NewNumberFromInt(255)}}, |
| 1777 {"for (var x = 0; x < 200; x = 2 * x + 1) {} return x;", |
| 1778 {factory->NewNumberFromInt(255)}}, |
| 1779 {"var sum = 0;\n" |
| 1780 "for (var x = 0; x < 200; x += 1) {\n" |
| 1781 " if (x % 2) continue;\n" |
| 1782 " if (sum > 10) break;\n" |
| 1783 " sum += x;\n" |
| 1784 "}\n" |
| 1785 "return sum;", |
| 1786 {factory->NewNumberFromInt(12)}}, |
| 1787 {"var sum = 0;\n" |
| 1788 "for (var w = 0; w < 2; w++) {\n" |
| 1789 " for (var x = 0; x < 200; x += 1) {\n" |
| 1790 " if (x % 2) continue;\n" |
| 1791 " if (x > 4) break;\n" |
| 1792 " sum += x + w;\n" |
| 1793 " }\n" |
| 1794 "}\n" |
| 1795 "return sum;", |
| 1796 {factory->NewNumberFromInt(15)}}, |
| 1797 {"var sum = 0;\n" |
| 1798 "for (var w = 0; w < 2; w++) {\n" |
| 1799 " if (w == 1) break;\n" |
| 1800 " for (var x = 0; x < 200; x += 1) {\n" |
| 1801 " if (x % 2) continue;\n" |
| 1802 " if (x > 4) break;\n" |
| 1803 " sum += x + w;\n" |
| 1804 " }\n" |
| 1805 "}\n" |
| 1806 "return sum;", |
| 1807 {factory->NewNumberFromInt(6)}}, |
| 1808 {"var sum = 0;\n" |
| 1809 "for (var w = 0; w < 3; w++) {\n" |
| 1810 " if (w == 1) continue;\n" |
| 1811 " for (var x = 0; x < 200; x += 1) {\n" |
| 1812 " if (x % 2) continue;\n" |
| 1813 " if (x > 4) break;\n" |
| 1814 " sum += x + w;\n" |
| 1815 " }\n" |
| 1816 "}\n" |
| 1817 "return sum;", |
| 1818 {factory->NewNumberFromInt(18)}}, |
| 1819 {"var sum = 0;\n" |
| 1820 "for (var x = 1; x < 10; x += 2) {\n" |
| 1821 " for (var y = x; y < x + 2; y++) {\n" |
| 1822 " sum += y * y;\n" |
| 1823 " }\n" |
| 1824 "}\n" |
| 1825 "return sum;", |
| 1826 {factory->NewNumberFromInt(385)}}, |
| 1827 }; |
| 1828 |
| 1829 for (size_t i = 0; i < arraysize(snippets); i++) { |
| 1830 ScopedVector<char> script(1024); |
| 1831 SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName, |
| 1832 snippets[i].code_snippet, kFunctionName); |
| 1833 |
| 1834 BytecodeGraphTester tester(isolate, zone, script.start()); |
| 1835 auto callable = tester.GetCallable<>(); |
| 1836 Handle<Object> return_value = callable().ToHandleChecked(); |
| 1837 CHECK(return_value->SameValue(*snippets[i].return_value())); |
| 1838 } |
| 1839 } |
| 1840 |
1451 } // namespace compiler | 1841 } // namespace compiler |
1452 } // namespace internal | 1842 } // namespace internal |
1453 } // namespace v8 | 1843 } // namespace v8 |
OLD | NEW |