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 1377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 i::Isolate* isolate = CcTest::i_isolate(); | 1394 i::Isolate* isolate = CcTest::i_isolate(); |
1395 i::Factory* factory = isolate->factory(); | 1395 i::Factory* factory = isolate->factory(); |
1396 | 1396 |
1397 uintptr_t stack_limit = isolate->stack_guard()->real_climit(); | 1397 uintptr_t stack_limit = isolate->stack_guard()->real_climit(); |
| 1398 int preparser_materialized_literals = -1; |
| 1399 int parser_materialized_literals = -2; |
1398 | 1400 |
1399 // Preparse the data. | 1401 // Preparse the data. |
1400 i::CompleteParserRecorder log; | 1402 i::CompleteParserRecorder log; |
1401 { | 1403 { |
1402 i::Scanner scanner(isolate->unicode_cache()); | 1404 i::Scanner scanner(isolate->unicode_cache()); |
1403 i::GenericStringUtf16CharacterStream stream(source, 0, source->length()); | 1405 i::GenericStringUtf16CharacterStream stream(source, 0, source->length()); |
1404 i::PreParser preparser(&scanner, &log, stack_limit); | 1406 i::PreParser preparser(&scanner, &log, stack_limit); |
1405 SetParserFlags(&preparser, flags); | 1407 SetParserFlags(&preparser, flags); |
1406 scanner.Initialize(&stream); | 1408 scanner.Initialize(&stream); |
1407 i::PreParser::PreParseResult result = preparser.PreParseProgram(); | 1409 i::PreParser::PreParseResult result = preparser.PreParseProgram( |
| 1410 &preparser_materialized_literals); |
1408 CHECK_EQ(i::PreParser::kPreParseSuccess, result); | 1411 CHECK_EQ(i::PreParser::kPreParseSuccess, result); |
1409 } | 1412 } |
1410 | 1413 |
1411 bool preparse_error = log.HasError(); | 1414 bool preparse_error = log.HasError(); |
1412 | 1415 |
1413 // Parse the data | 1416 // Parse the data |
1414 i::FunctionLiteral* function; | 1417 i::FunctionLiteral* function; |
1415 { | 1418 { |
1416 i::Handle<i::Script> script = factory->NewScript(source); | 1419 i::Handle<i::Script> script = factory->NewScript(source); |
1417 i::CompilationInfoWithZone info(script); | 1420 i::CompilationInfoWithZone info(script); |
1418 i::Parser::ParseInfo parse_info = {isolate->stack_guard()->real_climit(), | 1421 i::Parser::ParseInfo parse_info = {isolate->stack_guard()->real_climit(), |
1419 isolate->heap()->HashSeed(), | 1422 isolate->heap()->HashSeed(), |
1420 isolate->unicode_cache()}; | 1423 isolate->unicode_cache()}; |
1421 i::Parser parser(&info, &parse_info); | 1424 i::Parser parser(&info, &parse_info); |
1422 SetParserFlags(&parser, flags); | 1425 SetParserFlags(&parser, flags); |
1423 info.MarkAsGlobal(); | 1426 info.MarkAsGlobal(); |
1424 parser.Parse(); | 1427 parser.Parse(); |
1425 function = info.function(); | 1428 function = info.function(); |
| 1429 if (function) { |
| 1430 parser_materialized_literals = function->materialized_literal_count(); |
| 1431 } |
1426 } | 1432 } |
1427 | 1433 |
1428 // Check that preparsing fails iff parsing fails. | 1434 // Check that preparsing fails iff parsing fails. |
1429 if (function == NULL) { | 1435 if (function == NULL) { |
1430 // Extract exception from the parser. | 1436 // Extract exception from the parser. |
1431 CHECK(isolate->has_pending_exception()); | 1437 CHECK(isolate->has_pending_exception()); |
1432 i::Handle<i::JSObject> exception_handle( | 1438 i::Handle<i::JSObject> exception_handle( |
1433 i::JSObject::cast(isolate->pending_exception())); | 1439 i::JSObject::cast(isolate->pending_exception())); |
1434 i::Handle<i::String> message_string = | 1440 i::Handle<i::String> message_string = |
1435 i::Handle<i::String>::cast(i::Object::GetProperty( | 1441 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(), | 1487 source->ToCString().get(), |
1482 FormatMessage(log.ErrorMessageData())->ToCString().get()); | 1488 FormatMessage(log.ErrorMessageData())->ToCString().get()); |
1483 CHECK(false); | 1489 CHECK(false); |
1484 } else if (result == kError) { | 1490 } else if (result == kError) { |
1485 v8::base::OS::Print( | 1491 v8::base::OS::Print( |
1486 "Expected error on:\n" | 1492 "Expected error on:\n" |
1487 "\t%s\n" | 1493 "\t%s\n" |
1488 "However, parser and preparser succeeded", | 1494 "However, parser and preparser succeeded", |
1489 source->ToCString().get()); | 1495 source->ToCString().get()); |
1490 CHECK(false); | 1496 CHECK(false); |
| 1497 } else if (preparser_materialized_literals != parser_materialized_literals) { |
| 1498 v8::base::OS::Print( |
| 1499 "Preparser materialized literals (%d) differ from Parser materialized " |
| 1500 "literals (%d) on:\n" |
| 1501 "\t%s\n" |
| 1502 "However, parser and preparser succeeded", |
| 1503 preparser_materialized_literals, parser_materialized_literals, |
| 1504 source->ToCString().get()); |
| 1505 CHECK(false); |
1491 } | 1506 } |
1492 } | 1507 } |
1493 | 1508 |
1494 | 1509 |
1495 void TestParserSync(const char* source, | 1510 void TestParserSync(const char* source, |
1496 const ParserFlag* varying_flags, | 1511 const ParserFlag* varying_flags, |
1497 size_t varying_flags_length, | 1512 size_t varying_flags_length, |
1498 ParserSyncTestResult result = kSuccessOrError, | 1513 ParserSyncTestResult result = kSuccessOrError, |
1499 const ParserFlag* always_true_flags = NULL, | 1514 const ParserFlag* always_true_flags = NULL, |
1500 size_t always_true_flags_length = 0, | 1515 size_t always_true_flags_length = 0, |
(...skipping 2961 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4462 "tag`foo${\r\n a}`", | 4477 "tag`foo${\r\n a}`", |
4463 "tag`foo${\r a}`", | 4478 "tag`foo${\r a}`", |
4464 "tag`foo${'a' in a}`", | 4479 "tag`foo${'a' in a}`", |
4465 NULL}; | 4480 NULL}; |
4466 static const ParserFlag always_flags[] = {kAllowHarmonyTemplates}; | 4481 static const ParserFlag always_flags[] = {kAllowHarmonyTemplates}; |
4467 RunParserSyncTest(context_data, data, kSuccess, NULL, 0, always_flags, | 4482 RunParserSyncTest(context_data, data, kSuccess, NULL, 0, always_flags, |
4468 arraysize(always_flags)); | 4483 arraysize(always_flags)); |
4469 } | 4484 } |
4470 | 4485 |
4471 | 4486 |
| 4487 TEST(TemplateMaterializedLiterals) { |
| 4488 const char* context_data[][2] = { |
| 4489 { |
| 4490 "'use strict';\n" |
| 4491 "function tag() {}\n" |
| 4492 "var a, b, c;\n" |
| 4493 "(", ")" |
| 4494 }, |
| 4495 {NULL, NULL} |
| 4496 }; |
| 4497 |
| 4498 const char* data[] = { |
| 4499 "tag``", |
| 4500 "tag`a`", |
| 4501 "tag`a${1}b`", |
| 4502 "tag`a${1}b${2}c`", |
| 4503 "``", |
| 4504 "`a`", |
| 4505 "`a${1}b`", |
| 4506 "`a${1}b${2}c`", |
| 4507 NULL |
| 4508 }; |
| 4509 |
| 4510 static const ParserFlag always_flags[] = {kAllowHarmonyTemplates}; |
| 4511 RunParserSyncTest(context_data, data, kSuccess, NULL, 0, always_flags, |
| 4512 arraysize(always_flags)); |
| 4513 } |
| 4514 |
| 4515 |
4472 TEST(ScanUnterminatedTemplateLiterals) { | 4516 TEST(ScanUnterminatedTemplateLiterals) { |
4473 const char* context_data[][2] = {{"'use strict';", ""}, | 4517 const char* context_data[][2] = {{"'use strict';", ""}, |
4474 {"function foo(){ 'use strict';" | 4518 {"function foo(){ 'use strict';" |
4475 " var a, b, c; return ", "}"}, | 4519 " var a, b, c; return ", "}"}, |
4476 {NULL, NULL}}; | 4520 {NULL, NULL}}; |
4477 | 4521 |
4478 const char* data[] = { | 4522 const char* data[] = { |
4479 "`no-subst-template", | 4523 "`no-subst-template", |
4480 "`template-head${a}", | 4524 "`template-head${a}", |
4481 "`${a}template-tail", | 4525 "`${a}template-tail", |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4531 always_false_flags, arraysize(always_false_flags)); | 4575 always_false_flags, arraysize(always_false_flags)); |
4532 | 4576 |
4533 const char* good_data[] = { | 4577 const char* good_data[] = { |
4534 "let = 1;", | 4578 "let = 1;", |
4535 "for(let = 1;;){}", | 4579 "for(let = 1;;){}", |
4536 NULL}; | 4580 NULL}; |
4537 RunParserSyncTest(context_data, good_data, kSuccess, NULL, 0, | 4581 RunParserSyncTest(context_data, good_data, kSuccess, NULL, 0, |
4538 always_true_flags, arraysize(always_true_flags), | 4582 always_true_flags, arraysize(always_true_flags), |
4539 always_false_flags, arraysize(always_false_flags)); | 4583 always_false_flags, arraysize(always_false_flags)); |
4540 } | 4584 } |
OLD | NEW |