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 1372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |