Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(593)

Side by Side Diff: test/cctest/test-parsing.cc

Issue 792083002: Add materialized literals for tagged templates in preparser (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/preparser.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1372 matching lines...) Expand 10 before | Expand all | Expand 10 after
1383 flags.Contains(kAllowHarmonyArrowFunctions)); 1383 flags.Contains(kAllowHarmonyArrowFunctions));
1384 parser->set_allow_harmony_classes(flags.Contains(kAllowHarmonyClasses)); 1384 parser->set_allow_harmony_classes(flags.Contains(kAllowHarmonyClasses));
1385 parser->set_allow_harmony_templates(flags.Contains(kAllowHarmonyTemplates)); 1385 parser->set_allow_harmony_templates(flags.Contains(kAllowHarmonyTemplates));
1386 parser->set_allow_harmony_sloppy(flags.Contains(kAllowHarmonySloppy)); 1386 parser->set_allow_harmony_sloppy(flags.Contains(kAllowHarmonySloppy));
1387 parser->set_allow_harmony_unicode(flags.Contains(kAllowHarmonyUnicode)); 1387 parser->set_allow_harmony_unicode(flags.Contains(kAllowHarmonyUnicode));
1388 } 1388 }
1389 1389
1390 1390
1391 void TestParserSyncWithFlags(i::Handle<i::String> source, 1391 void TestParserSyncWithFlags(i::Handle<i::String> source,
1392 i::EnumSet<ParserFlag> flags, 1392 i::EnumSet<ParserFlag> flags,
1393 ParserSyncTestResult result) { 1393 ParserSyncTestResult result,
1394 int literals = -1) {
Dmitry Lomov (no reviews) 2014/12/10 18:49:31 Instead of passing the expected number of literals
1394 i::Isolate* isolate = CcTest::i_isolate(); 1395 i::Isolate* isolate = CcTest::i_isolate();
1395 i::Factory* factory = isolate->factory(); 1396 i::Factory* factory = isolate->factory();
1396 1397
1397 uintptr_t stack_limit = isolate->stack_guard()->real_climit(); 1398 uintptr_t stack_limit = isolate->stack_guard()->real_climit();
1398 1399
1399 // Preparse the data. 1400 // Preparse the data.
1400 i::CompleteParserRecorder log; 1401 i::CompleteParserRecorder log;
1401 { 1402 {
1402 i::Scanner scanner(isolate->unicode_cache()); 1403 i::Scanner scanner(isolate->unicode_cache());
1403 i::GenericStringUtf16CharacterStream stream(source, 0, source->length()); 1404 i::GenericStringUtf16CharacterStream stream(source, 0, source->length());
1404 i::PreParser preparser(&scanner, &log, stack_limit); 1405 i::PreParser preparser(&scanner, &log, stack_limit);
1405 SetParserFlags(&preparser, flags); 1406 SetParserFlags(&preparser, flags);
1406 scanner.Initialize(&stream); 1407 scanner.Initialize(&stream);
1407 i::PreParser::PreParseResult result = preparser.PreParseProgram(); 1408 i::PreParser::PreParseResult result = preparser.PreParseProgram();
1408 CHECK_EQ(i::PreParser::kPreParseSuccess, result); 1409 CHECK_EQ(i::PreParser::kPreParseSuccess, result);
1409 } 1410 }
1410 1411
1411 bool preparse_error = log.HasError(); 1412 bool preparse_error = log.HasError();
1412 1413 int actual_materialized_literals;
1413 // Parse the data 1414 // Parse the data
1414 i::FunctionLiteral* function; 1415 i::FunctionLiteral* function;
1415 { 1416 {
1416 i::Handle<i::Script> script = factory->NewScript(source); 1417 i::Handle<i::Script> script = factory->NewScript(source);
1417 i::CompilationInfoWithZone info(script); 1418 i::CompilationInfoWithZone info(script);
1418 i::Parser::ParseInfo parse_info = {isolate->stack_guard()->real_climit(), 1419 i::Parser::ParseInfo parse_info = {isolate->stack_guard()->real_climit(),
1419 isolate->heap()->HashSeed(), 1420 isolate->heap()->HashSeed(),
1420 isolate->unicode_cache()}; 1421 isolate->unicode_cache()};
1421 i::Parser parser(&info, &parse_info); 1422 i::Parser parser(&info, &parse_info);
1422 SetParserFlags(&parser, flags); 1423 SetParserFlags(&parser, flags);
1423 info.MarkAsGlobal(); 1424 info.MarkAsGlobal();
1424 parser.Parse(); 1425 parser.Parse();
1425 function = info.function(); 1426 function = info.function();
1427 if (function) {
1428 actual_materialized_literals = function->materialized_literal_count();
caitp (gmail) 2014/12/10 18:17:49 have to do this here because the contents of the f
1429 }
1426 } 1430 }
1427 1431
1428 // Check that preparsing fails iff parsing fails. 1432 // Check that preparsing fails iff parsing fails.
1429 if (function == NULL) { 1433 if (function == NULL) {
1430 // Extract exception from the parser. 1434 // Extract exception from the parser.
1431 CHECK(isolate->has_pending_exception()); 1435 CHECK(isolate->has_pending_exception());
1432 i::Handle<i::JSObject> exception_handle( 1436 i::Handle<i::JSObject> exception_handle(
1433 i::JSObject::cast(isolate->pending_exception())); 1437 i::JSObject::cast(isolate->pending_exception()));
1434 i::Handle<i::String> message_string = 1438 i::Handle<i::String> message_string =
1435 i::Handle<i::String>::cast(i::Object::GetProperty( 1439 i::Handle<i::String>::cast(i::Object::GetProperty(
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1481 source->ToCString().get(), 1485 source->ToCString().get(),
1482 FormatMessage(log.ErrorMessageData())->ToCString().get()); 1486 FormatMessage(log.ErrorMessageData())->ToCString().get());
1483 CHECK(false); 1487 CHECK(false);
1484 } else if (result == kError) { 1488 } else if (result == kError) {
1485 v8::base::OS::Print( 1489 v8::base::OS::Print(
1486 "Expected error on:\n" 1490 "Expected error on:\n"
1487 "\t%s\n" 1491 "\t%s\n"
1488 "However, parser and preparser succeeded", 1492 "However, parser and preparser succeeded",
1489 source->ToCString().get()); 1493 source->ToCString().get());
1490 CHECK(false); 1494 CHECK(false);
1495 } else if (literals > -1) {
1496 if (actual_materialized_literals != literals) {
1497 v8::base::OS::Print(
1498 "Expected parsed function to have %d materialized literals, "
1499 "but it had %d.", literals, actual_materialized_literals
1500 );
1501 CHECK(false);
1502 }
1491 } 1503 }
1492 } 1504 }
1493 1505
1494 1506
1495 void TestParserSync(const char* source, 1507 void TestParserSync(const char* source,
1496 const ParserFlag* varying_flags, 1508 const ParserFlag* varying_flags,
1497 size_t varying_flags_length, 1509 size_t varying_flags_length,
1498 ParserSyncTestResult result = kSuccessOrError, 1510 ParserSyncTestResult result = kSuccessOrError,
1499 const ParserFlag* always_true_flags = NULL, 1511 const ParserFlag* always_true_flags = NULL,
1500 size_t always_true_flags_length = 0, 1512 size_t always_true_flags_length = 0,
1501 const ParserFlag* always_false_flags = NULL, 1513 const ParserFlag* always_false_flags = NULL,
1502 size_t always_false_flags_length = 0) { 1514 size_t always_false_flags_length = 0,
1515 int literals = -1) {
1503 i::Handle<i::String> str = 1516 i::Handle<i::String> str =
1504 CcTest::i_isolate()->factory()->NewStringFromAsciiChecked(source); 1517 CcTest::i_isolate()->factory()->NewStringFromAsciiChecked(source);
1505 for (int bits = 0; bits < (1 << varying_flags_length); bits++) { 1518 for (int bits = 0; bits < (1 << varying_flags_length); bits++) {
1506 i::EnumSet<ParserFlag> flags; 1519 i::EnumSet<ParserFlag> flags;
1507 for (size_t flag_index = 0; flag_index < varying_flags_length; 1520 for (size_t flag_index = 0; flag_index < varying_flags_length;
1508 ++flag_index) { 1521 ++flag_index) {
1509 if ((bits & (1 << flag_index)) != 0) flags.Add(varying_flags[flag_index]); 1522 if ((bits & (1 << flag_index)) != 0) flags.Add(varying_flags[flag_index]);
1510 } 1523 }
1511 for (size_t flag_index = 0; flag_index < always_true_flags_length; 1524 for (size_t flag_index = 0; flag_index < always_true_flags_length;
1512 ++flag_index) { 1525 ++flag_index) {
1513 flags.Add(always_true_flags[flag_index]); 1526 flags.Add(always_true_flags[flag_index]);
1514 } 1527 }
1515 for (size_t flag_index = 0; flag_index < always_false_flags_length; 1528 for (size_t flag_index = 0; flag_index < always_false_flags_length;
1516 ++flag_index) { 1529 ++flag_index) {
1517 flags.Remove(always_false_flags[flag_index]); 1530 flags.Remove(always_false_flags[flag_index]);
1518 } 1531 }
1519 TestParserSyncWithFlags(str, flags, result); 1532 TestParserSyncWithFlags(str, flags, result, literals);
1520 } 1533 }
1521 } 1534 }
1522 1535
1523 1536
1524 TEST(ParserSync) { 1537 TEST(ParserSync) {
1525 const char* context_data[][2] = { 1538 const char* context_data[][2] = {
1526 { "", "" }, 1539 { "", "" },
1527 { "{", "}" }, 1540 { "{", "}" },
1528 { "if (true) ", " else {}" }, 1541 { "if (true) ", " else {}" },
1529 { "if (true) {} else ", "" }, 1542 { "if (true) {} else ", "" },
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
1658 1671
1659 1672
1660 void RunParserSyncTest(const char* context_data[][2], 1673 void RunParserSyncTest(const char* context_data[][2],
1661 const char* statement_data[], 1674 const char* statement_data[],
1662 ParserSyncTestResult result, 1675 ParserSyncTestResult result,
1663 const ParserFlag* flags = NULL, 1676 const ParserFlag* flags = NULL,
1664 int flags_len = 0, 1677 int flags_len = 0,
1665 const ParserFlag* always_true_flags = NULL, 1678 const ParserFlag* always_true_flags = NULL,
1666 int always_true_len = 0, 1679 int always_true_len = 0,
1667 const ParserFlag* always_false_flags = NULL, 1680 const ParserFlag* always_false_flags = NULL,
1668 int always_false_len = 0) { 1681 int always_false_len = 0,
1682 const int* expected_literals = NULL) {
1669 v8::HandleScope handles(CcTest::isolate()); 1683 v8::HandleScope handles(CcTest::isolate());
1670 v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate()); 1684 v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate());
1671 v8::Context::Scope context_scope(context); 1685 v8::Context::Scope context_scope(context);
1672 1686
1673 CcTest::i_isolate()->stack_guard()->SetStackLimit( 1687 CcTest::i_isolate()->stack_guard()->SetStackLimit(
1674 i::GetCurrentStackPosition() - 128 * 1024); 1688 i::GetCurrentStackPosition() - 128 * 1024);
1675 1689
1676 // Experimental feature flags should not go here; pass the flags as 1690 // Experimental feature flags should not go here; pass the flags as
1677 // always_true_flags if the test needs them. 1691 // always_true_flags if the test needs them.
1678 static const ParserFlag default_flags[] = { 1692 static const ParserFlag default_flags[] = {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1710 int kSuffixLen = i::StrLength(context_data[i][1]); 1724 int kSuffixLen = i::StrLength(context_data[i][1]);
1711 int kProgramSize = kPrefixLen + kStatementLen + kSuffixLen; 1725 int kProgramSize = kPrefixLen + kStatementLen + kSuffixLen;
1712 1726
1713 // Plug the source code pieces together. 1727 // Plug the source code pieces together.
1714 i::ScopedVector<char> program(kProgramSize + 1); 1728 i::ScopedVector<char> program(kProgramSize + 1);
1715 int length = i::SNPrintF(program, 1729 int length = i::SNPrintF(program,
1716 "%s%s%s", 1730 "%s%s%s",
1717 context_data[i][0], 1731 context_data[i][0],
1718 statement_data[j], 1732 statement_data[j],
1719 context_data[i][1]); 1733 context_data[i][1]);
1734 int expected_literal_count = -1;
1735 if (expected_literals) {
1736 expected_literal_count = expected_literals[j];
1737 }
1720 CHECK(length == kProgramSize); 1738 CHECK(length == kProgramSize);
1721 TestParserSync(program.start(), 1739 TestParserSync(program.start(),
1722 flags, 1740 flags,
1723 flags_len, 1741 flags_len,
1724 result, 1742 result,
1725 always_true_flags, 1743 always_true_flags,
1726 always_true_len, 1744 always_true_len,
1727 always_false_flags, 1745 always_false_flags,
1728 always_false_len); 1746 always_false_len,
1747 expected_literal_count);
1729 } 1748 }
1730 } 1749 }
1731 delete[] generated_flags; 1750 delete[] generated_flags;
1732 } 1751 }
1733 1752
1734 1753
1735 TEST(ErrorsEvalAndArguments) { 1754 TEST(ErrorsEvalAndArguments) {
1736 // Tests that both preparsing and parsing produce the right kind of errors for 1755 // Tests that both preparsing and parsing produce the right kind of errors for
1737 // using "eval" and "arguments" as identifiers. Without the strict mode, it's 1756 // using "eval" and "arguments" as identifiers. Without the strict mode, it's
1738 // ok to use "eval" or "arguments" as identifiers. With the strict mode, it 1757 // ok to use "eval" or "arguments" as identifiers. With the strict mode, it
(...skipping 2723 matching lines...) Expand 10 before | Expand all | Expand 10 after
4462 "tag`foo${\r\n a}`", 4481 "tag`foo${\r\n a}`",
4463 "tag`foo${\r a}`", 4482 "tag`foo${\r a}`",
4464 "tag`foo${'a' in a}`", 4483 "tag`foo${'a' in a}`",
4465 NULL}; 4484 NULL};
4466 static const ParserFlag always_flags[] = {kAllowHarmonyTemplates}; 4485 static const ParserFlag always_flags[] = {kAllowHarmonyTemplates};
4467 RunParserSyncTest(context_data, data, kSuccess, NULL, 0, always_flags, 4486 RunParserSyncTest(context_data, data, kSuccess, NULL, 0, always_flags,
4468 arraysize(always_flags)); 4487 arraysize(always_flags));
4469 } 4488 }
4470 4489
4471 4490
4491 TEST(TaggedTemplateMaterializedLiterals) {
4492 const char* context_data[][2] = {
4493 {
4494 "// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n"
4495 "// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n"
4496 "// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n"
4497 "// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n"
4498 "// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n"
4499 "// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n"
4500 "// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n"
4501 "// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n"
4502 "// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n"
4503 "// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n"
4504 "// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n"
4505 "// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n"
4506 "// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n"
4507 "'use strict';",
caitp (gmail) 2014/12/10 18:17:49 (lldb) p actual_materialized_literals (int) $16 =
4508 ""
4509 },
4510 {
4511 "function test(){ 'use strict';"
4512 " function tag() {}"
4513 " var a, b, c; return ",
4514 "}"
4515 },
4516 {NULL, NULL}
4517 };
4518
4519 const char* data[] = {
4520 "tag``;",
4521 "tag`a`;",
4522 "tag`a${1}b`;",
4523 "tag`a${1}b${2}c`;",
4524 NULL
4525 };
4526
4527 const int literals[] = {
4528 2,
4529 2,
4530 2,
4531 2
4532 };
4533
4534 static const ParserFlag always_flags[] = {kAllowHarmonyTemplates};
4535 RunParserSyncTest(context_data, data, kSuccess, NULL, 0, always_flags,
4536 arraysize(always_flags), NULL, 0, literals);
4537 }
4538
4539
4472 TEST(ScanUnterminatedTemplateLiterals) { 4540 TEST(ScanUnterminatedTemplateLiterals) {
4473 const char* context_data[][2] = {{"'use strict';", ""}, 4541 const char* context_data[][2] = {{"'use strict';", ""},
4474 {"function foo(){ 'use strict';" 4542 {"function foo(){ 'use strict';"
4475 " var a, b, c; return ", "}"}, 4543 " var a, b, c; return ", "}"},
4476 {NULL, NULL}}; 4544 {NULL, NULL}};
4477 4545
4478 const char* data[] = { 4546 const char* data[] = {
4479 "`no-subst-template", 4547 "`no-subst-template",
4480 "`template-head${a}", 4548 "`template-head${a}",
4481 "`${a}template-tail", 4549 "`${a}template-tail",
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
4531 always_false_flags, arraysize(always_false_flags)); 4599 always_false_flags, arraysize(always_false_flags));
4532 4600
4533 const char* good_data[] = { 4601 const char* good_data[] = {
4534 "let = 1;", 4602 "let = 1;",
4535 "for(let = 1;;){}", 4603 "for(let = 1;;){}",
4536 NULL}; 4604 NULL};
4537 RunParserSyncTest(context_data, good_data, kSuccess, NULL, 0, 4605 RunParserSyncTest(context_data, good_data, kSuccess, NULL, 0,
4538 always_true_flags, arraysize(always_true_flags), 4606 always_true_flags, arraysize(always_true_flags),
4539 always_false_flags, arraysize(always_false_flags)); 4607 always_false_flags, arraysize(always_false_flags));
4540 } 4608 }
OLDNEW
« no previous file with comments | « src/preparser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698