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 |