| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 1517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1528 flags.Contains(kAllowHarmonyRestrictiveDeclarations)); | 1528 flags.Contains(kAllowHarmonyRestrictiveDeclarations)); |
| 1529 parser->set_allow_harmony_exponentiation_operator( | 1529 parser->set_allow_harmony_exponentiation_operator( |
| 1530 flags.Contains(kAllowHarmonyExponentiationOperator)); | 1530 flags.Contains(kAllowHarmonyExponentiationOperator)); |
| 1531 parser->set_allow_harmony_for_in(flags.Contains(kAllowHarmonyForIn)); | 1531 parser->set_allow_harmony_for_in(flags.Contains(kAllowHarmonyForIn)); |
| 1532 } | 1532 } |
| 1533 | 1533 |
| 1534 | 1534 |
| 1535 void TestParserSyncWithFlags(i::Handle<i::String> source, | 1535 void TestParserSyncWithFlags(i::Handle<i::String> source, |
| 1536 i::EnumSet<ParserFlag> flags, | 1536 i::EnumSet<ParserFlag> flags, |
| 1537 ParserSyncTestResult result, | 1537 ParserSyncTestResult result, |
| 1538 bool is_module = false) { | 1538 bool is_module = false, |
| 1539 bool test_preparser = true) { |
| 1539 i::Isolate* isolate = CcTest::i_isolate(); | 1540 i::Isolate* isolate = CcTest::i_isolate(); |
| 1540 i::Factory* factory = isolate->factory(); | 1541 i::Factory* factory = isolate->factory(); |
| 1541 | 1542 |
| 1542 uintptr_t stack_limit = isolate->stack_guard()->real_climit(); | 1543 uintptr_t stack_limit = isolate->stack_guard()->real_climit(); |
| 1543 int preparser_materialized_literals = -1; | 1544 int preparser_materialized_literals = -1; |
| 1544 int parser_materialized_literals = -2; | 1545 int parser_materialized_literals = -2; |
| 1545 | 1546 |
| 1546 // Preparse the data. | 1547 // Preparse the data. |
| 1547 i::CompleteParserRecorder log; | 1548 i::CompleteParserRecorder log; |
| 1548 { | 1549 if (test_preparser) { |
| 1549 i::Scanner scanner(isolate->unicode_cache()); | 1550 i::Scanner scanner(isolate->unicode_cache()); |
| 1550 i::GenericStringUtf16CharacterStream stream(source, 0, source->length()); | 1551 i::GenericStringUtf16CharacterStream stream(source, 0, source->length()); |
| 1551 i::Zone zone(CcTest::i_isolate()->allocator()); | 1552 i::Zone zone(CcTest::i_isolate()->allocator()); |
| 1552 i::AstValueFactory ast_value_factory( | 1553 i::AstValueFactory ast_value_factory( |
| 1553 &zone, CcTest::i_isolate()->heap()->HashSeed()); | 1554 &zone, CcTest::i_isolate()->heap()->HashSeed()); |
| 1554 i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log, | 1555 i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log, |
| 1555 stack_limit); | 1556 stack_limit); |
| 1556 SetParserFlags(&preparser, flags); | 1557 SetParserFlags(&preparser, flags); |
| 1557 scanner.Initialize(&stream); | 1558 scanner.Initialize(&stream); |
| 1558 i::PreParser::PreParseResult result = | 1559 i::PreParser::PreParseResult result = |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1595 v8::base::OS::Print( | 1596 v8::base::OS::Print( |
| 1596 "Parser failed on:\n" | 1597 "Parser failed on:\n" |
| 1597 "\t%s\n" | 1598 "\t%s\n" |
| 1598 "with error:\n" | 1599 "with error:\n" |
| 1599 "\t%s\n" | 1600 "\t%s\n" |
| 1600 "However, we expected no error.", | 1601 "However, we expected no error.", |
| 1601 source->ToCString().get(), message_string->ToCString().get()); | 1602 source->ToCString().get(), message_string->ToCString().get()); |
| 1602 CHECK(false); | 1603 CHECK(false); |
| 1603 } | 1604 } |
| 1604 | 1605 |
| 1605 if (!preparse_error) { | 1606 if (test_preparser && !preparse_error) { |
| 1606 v8::base::OS::Print( | 1607 v8::base::OS::Print( |
| 1607 "Parser failed on:\n" | 1608 "Parser failed on:\n" |
| 1608 "\t%s\n" | 1609 "\t%s\n" |
| 1609 "with error:\n" | 1610 "with error:\n" |
| 1610 "\t%s\n" | 1611 "\t%s\n" |
| 1611 "However, the preparser succeeded", | 1612 "However, the preparser succeeded", |
| 1612 source->ToCString().get(), message_string->ToCString().get()); | 1613 source->ToCString().get(), message_string->ToCString().get()); |
| 1613 CHECK(false); | 1614 CHECK(false); |
| 1614 } | 1615 } |
| 1615 // Check that preparser and parser produce the same error. | 1616 // Check that preparser and parser produce the same error. |
| 1616 { | 1617 if (test_preparser) { |
| 1617 i::Handle<i::String> preparser_message = | 1618 i::Handle<i::String> preparser_message = |
| 1618 FormatMessage(log.ErrorMessageData()); | 1619 FormatMessage(log.ErrorMessageData()); |
| 1619 if (!i::String::Equals(message_string, preparser_message)) { | 1620 if (!i::String::Equals(message_string, preparser_message)) { |
| 1620 v8::base::OS::Print( | 1621 v8::base::OS::Print( |
| 1621 "Expected parser and preparser to produce the same error on:\n" | 1622 "Expected parser and preparser to produce the same error on:\n" |
| 1622 "\t%s\n" | 1623 "\t%s\n" |
| 1623 "However, found the following error messages\n" | 1624 "However, found the following error messages\n" |
| 1624 "\tparser: %s\n" | 1625 "\tparser: %s\n" |
| 1625 "\tpreparser: %s\n", | 1626 "\tpreparser: %s\n", |
| 1626 source->ToCString().get(), message_string->ToCString().get(), | 1627 source->ToCString().get(), message_string->ToCString().get(), |
| 1627 preparser_message->ToCString().get()); | 1628 preparser_message->ToCString().get()); |
| 1628 CHECK(false); | 1629 CHECK(false); |
| 1629 } | 1630 } |
| 1630 } | 1631 } |
| 1631 } else if (preparse_error) { | 1632 } else if (test_preparser && preparse_error) { |
| 1632 v8::base::OS::Print( | 1633 v8::base::OS::Print( |
| 1633 "Preparser failed on:\n" | 1634 "Preparser failed on:\n" |
| 1634 "\t%s\n" | 1635 "\t%s\n" |
| 1635 "with error:\n" | 1636 "with error:\n" |
| 1636 "\t%s\n" | 1637 "\t%s\n" |
| 1637 "However, the parser succeeded", | 1638 "However, the parser succeeded", |
| 1638 source->ToCString().get(), | 1639 source->ToCString().get(), |
| 1639 FormatMessage(log.ErrorMessageData())->ToCString().get()); | 1640 FormatMessage(log.ErrorMessageData())->ToCString().get()); |
| 1640 CHECK(false); | 1641 CHECK(false); |
| 1641 } else if (result == kError) { | 1642 } else if (result == kError) { |
| 1642 v8::base::OS::Print( | 1643 v8::base::OS::Print( |
| 1643 "Expected error on:\n" | 1644 "Expected error on:\n" |
| 1644 "\t%s\n" | 1645 "\t%s\n" |
| 1645 "However, parser and preparser succeeded", | 1646 "However, parser and preparser succeeded", |
| 1646 source->ToCString().get()); | 1647 source->ToCString().get()); |
| 1647 CHECK(false); | 1648 CHECK(false); |
| 1648 } else if (preparser_materialized_literals != parser_materialized_literals) { | 1649 } else if (test_preparser && |
| 1650 preparser_materialized_literals != parser_materialized_literals) { |
| 1649 v8::base::OS::Print( | 1651 v8::base::OS::Print( |
| 1650 "Preparser materialized literals (%d) differ from Parser materialized " | 1652 "Preparser materialized literals (%d) differ from Parser materialized " |
| 1651 "literals (%d) on:\n" | 1653 "literals (%d) on:\n" |
| 1652 "\t%s\n" | 1654 "\t%s\n" |
| 1653 "However, parser and preparser succeeded", | 1655 "However, parser and preparser succeeded", |
| 1654 preparser_materialized_literals, parser_materialized_literals, | 1656 preparser_materialized_literals, parser_materialized_literals, |
| 1655 source->ToCString().get()); | 1657 source->ToCString().get()); |
| 1656 CHECK(false); | 1658 CHECK(false); |
| 1657 } | 1659 } |
| 1658 } | 1660 } |
| 1659 | 1661 |
| 1660 | 1662 |
| 1661 void TestParserSync(const char* source, const ParserFlag* varying_flags, | 1663 void TestParserSync(const char* source, const ParserFlag* varying_flags, |
| 1662 size_t varying_flags_length, | 1664 size_t varying_flags_length, |
| 1663 ParserSyncTestResult result = kSuccessOrError, | 1665 ParserSyncTestResult result = kSuccessOrError, |
| 1664 const ParserFlag* always_true_flags = NULL, | 1666 const ParserFlag* always_true_flags = NULL, |
| 1665 size_t always_true_flags_length = 0, | 1667 size_t always_true_flags_length = 0, |
| 1666 const ParserFlag* always_false_flags = NULL, | 1668 const ParserFlag* always_false_flags = NULL, |
| 1667 size_t always_false_flags_length = 0, | 1669 size_t always_false_flags_length = 0, |
| 1668 bool is_module = false) { | 1670 bool is_module = false, bool test_preparser = true) { |
| 1669 i::Handle<i::String> str = | 1671 i::Handle<i::String> str = |
| 1670 CcTest::i_isolate()->factory()->NewStringFromAsciiChecked(source); | 1672 CcTest::i_isolate()->factory()->NewStringFromAsciiChecked(source); |
| 1671 for (int bits = 0; bits < (1 << varying_flags_length); bits++) { | 1673 for (int bits = 0; bits < (1 << varying_flags_length); bits++) { |
| 1672 i::EnumSet<ParserFlag> flags; | 1674 i::EnumSet<ParserFlag> flags; |
| 1673 for (size_t flag_index = 0; flag_index < varying_flags_length; | 1675 for (size_t flag_index = 0; flag_index < varying_flags_length; |
| 1674 ++flag_index) { | 1676 ++flag_index) { |
| 1675 if ((bits & (1 << flag_index)) != 0) flags.Add(varying_flags[flag_index]); | 1677 if ((bits & (1 << flag_index)) != 0) flags.Add(varying_flags[flag_index]); |
| 1676 } | 1678 } |
| 1677 for (size_t flag_index = 0; flag_index < always_true_flags_length; | 1679 for (size_t flag_index = 0; flag_index < always_true_flags_length; |
| 1678 ++flag_index) { | 1680 ++flag_index) { |
| 1679 flags.Add(always_true_flags[flag_index]); | 1681 flags.Add(always_true_flags[flag_index]); |
| 1680 } | 1682 } |
| 1681 for (size_t flag_index = 0; flag_index < always_false_flags_length; | 1683 for (size_t flag_index = 0; flag_index < always_false_flags_length; |
| 1682 ++flag_index) { | 1684 ++flag_index) { |
| 1683 flags.Remove(always_false_flags[flag_index]); | 1685 flags.Remove(always_false_flags[flag_index]); |
| 1684 } | 1686 } |
| 1685 TestParserSyncWithFlags(str, flags, result, is_module); | 1687 TestParserSyncWithFlags(str, flags, result, is_module, test_preparser); |
| 1686 } | 1688 } |
| 1687 } | 1689 } |
| 1688 | 1690 |
| 1689 | 1691 |
| 1690 TEST(ParserSync) { | 1692 TEST(ParserSync) { |
| 1691 const char* context_data[][2] = { | 1693 const char* context_data[][2] = { |
| 1692 { "", "" }, | 1694 { "", "" }, |
| 1693 { "{", "}" }, | 1695 { "{", "}" }, |
| 1694 { "if (true) ", " else {}" }, | 1696 { "if (true) ", " else {}" }, |
| 1695 { "if (true) {} else ", "" }, | 1697 { "if (true) {} else ", "" }, |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1823 } | 1825 } |
| 1824 | 1826 |
| 1825 | 1827 |
| 1826 void RunParserSyncTest(const char* context_data[][2], | 1828 void RunParserSyncTest(const char* context_data[][2], |
| 1827 const char* statement_data[], | 1829 const char* statement_data[], |
| 1828 ParserSyncTestResult result, | 1830 ParserSyncTestResult result, |
| 1829 const ParserFlag* flags = NULL, int flags_len = 0, | 1831 const ParserFlag* flags = NULL, int flags_len = 0, |
| 1830 const ParserFlag* always_true_flags = NULL, | 1832 const ParserFlag* always_true_flags = NULL, |
| 1831 int always_true_len = 0, | 1833 int always_true_len = 0, |
| 1832 const ParserFlag* always_false_flags = NULL, | 1834 const ParserFlag* always_false_flags = NULL, |
| 1833 int always_false_len = 0, bool is_module = false) { | 1835 int always_false_len = 0, bool is_module = false, |
| 1836 bool test_preparser = true) { |
| 1834 v8::HandleScope handles(CcTest::isolate()); | 1837 v8::HandleScope handles(CcTest::isolate()); |
| 1835 v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate()); | 1838 v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate()); |
| 1836 v8::Context::Scope context_scope(context); | 1839 v8::Context::Scope context_scope(context); |
| 1837 | 1840 |
| 1838 CcTest::i_isolate()->stack_guard()->SetStackLimit( | 1841 CcTest::i_isolate()->stack_guard()->SetStackLimit( |
| 1839 i::GetCurrentStackPosition() - 128 * 1024); | 1842 i::GetCurrentStackPosition() - 128 * 1024); |
| 1840 | 1843 |
| 1841 // Experimental feature flags should not go here; pass the flags as | 1844 // Experimental feature flags should not go here; pass the flags as |
| 1842 // always_true_flags if the test needs them. | 1845 // always_true_flags if the test needs them. |
| 1843 static const ParserFlag default_flags[] = { | 1846 static const ParserFlag default_flags[] = { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1878 // Plug the source code pieces together. | 1881 // Plug the source code pieces together. |
| 1879 i::ScopedVector<char> program(kProgramSize + 1); | 1882 i::ScopedVector<char> program(kProgramSize + 1); |
| 1880 int length = i::SNPrintF(program, | 1883 int length = i::SNPrintF(program, |
| 1881 "%s%s%s", | 1884 "%s%s%s", |
| 1882 context_data[i][0], | 1885 context_data[i][0], |
| 1883 statement_data[j], | 1886 statement_data[j], |
| 1884 context_data[i][1]); | 1887 context_data[i][1]); |
| 1885 CHECK(length == kProgramSize); | 1888 CHECK(length == kProgramSize); |
| 1886 TestParserSync(program.start(), flags, flags_len, result, | 1889 TestParserSync(program.start(), flags, flags_len, result, |
| 1887 always_true_flags, always_true_len, always_false_flags, | 1890 always_true_flags, always_true_len, always_false_flags, |
| 1888 always_false_len, is_module); | 1891 always_false_len, is_module, test_preparser); |
| 1889 } | 1892 } |
| 1890 } | 1893 } |
| 1891 delete[] generated_flags; | 1894 delete[] generated_flags; |
| 1892 } | 1895 } |
| 1893 | 1896 |
| 1894 | 1897 |
| 1895 void RunModuleParserSyncTest(const char* context_data[][2], | 1898 void RunModuleParserSyncTest(const char* context_data[][2], |
| 1896 const char* statement_data[], | 1899 const char* statement_data[], |
| 1897 ParserSyncTestResult result, | 1900 ParserSyncTestResult result, |
| 1898 const ParserFlag* flags = NULL, int flags_len = 0, | 1901 const ParserFlag* flags = NULL, int flags_len = 0, |
| 1899 const ParserFlag* always_true_flags = NULL, | 1902 const ParserFlag* always_true_flags = NULL, |
| 1900 int always_true_len = 0, | 1903 int always_true_len = 0, |
| 1901 const ParserFlag* always_false_flags = NULL, | 1904 const ParserFlag* always_false_flags = NULL, |
| 1902 int always_false_len = 0) { | 1905 int always_false_len = 0, |
| 1906 bool test_preparser = true) { |
| 1903 RunParserSyncTest(context_data, statement_data, result, flags, flags_len, | 1907 RunParserSyncTest(context_data, statement_data, result, flags, flags_len, |
| 1904 always_true_flags, always_true_len, always_false_flags, | 1908 always_true_flags, always_true_len, always_false_flags, |
| 1905 always_false_len, true); | 1909 always_false_len, true, test_preparser); |
| 1906 } | 1910 } |
| 1907 | 1911 |
| 1908 | 1912 |
| 1909 TEST(ErrorsEvalAndArguments) { | 1913 TEST(ErrorsEvalAndArguments) { |
| 1910 // Tests that both preparsing and parsing produce the right kind of errors for | 1914 // Tests that both preparsing and parsing produce the right kind of errors for |
| 1911 // using "eval" and "arguments" as identifiers. Without the strict mode, it's | 1915 // using "eval" and "arguments" as identifiers. Without the strict mode, it's |
| 1912 // ok to use "eval" or "arguments" as identifiers. With the strict mode, it | 1916 // ok to use "eval" or "arguments" as identifiers. With the strict mode, it |
| 1913 // isn't. | 1917 // isn't. |
| 1914 const char* context_data[][2] = { | 1918 const char* context_data[][2] = { |
| 1915 {"\"use strict\";", ""}, | 1919 {"\"use strict\";", ""}, |
| (...skipping 5533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7449 "for (const x = 0 in {});", | 7453 "for (const x = 0 in {});", |
| 7450 "for (let x = 0 in {});", | 7454 "for (let x = 0 in {});", |
| 7451 NULL | 7455 NULL |
| 7452 }; | 7456 }; |
| 7453 // clang-format on | 7457 // clang-format on |
| 7454 | 7458 |
| 7455 static const ParserFlag always_flags[] = {kAllowHarmonyForIn}; | 7459 static const ParserFlag always_flags[] = {kAllowHarmonyForIn}; |
| 7456 RunParserSyncTest(context_data, error_data, kError, nullptr, 0, always_flags, | 7460 RunParserSyncTest(context_data, error_data, kError, nullptr, 0, always_flags, |
| 7457 arraysize(always_flags)); | 7461 arraysize(always_flags)); |
| 7458 } | 7462 } |
| OLD | NEW |