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

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

Issue 154243005: Better tests for the Parser / Preparser unification. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 10 months 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | 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 1094 matching lines...) Expand 10 before | Expand all | Expand 10 after
1105 parser->set_allow_harmony_scoping(flags.Contains(kAllowHarmonyScoping)); 1105 parser->set_allow_harmony_scoping(flags.Contains(kAllowHarmonyScoping));
1106 parser->set_allow_modules(flags.Contains(kAllowModules)); 1106 parser->set_allow_modules(flags.Contains(kAllowModules));
1107 parser->set_allow_generators(flags.Contains(kAllowGenerators)); 1107 parser->set_allow_generators(flags.Contains(kAllowGenerators));
1108 parser->set_allow_for_of(flags.Contains(kAllowForOf)); 1108 parser->set_allow_for_of(flags.Contains(kAllowForOf));
1109 parser->set_allow_harmony_numeric_literals( 1109 parser->set_allow_harmony_numeric_literals(
1110 flags.Contains(kAllowHarmonyNumericLiterals)); 1110 flags.Contains(kAllowHarmonyNumericLiterals));
1111 } 1111 }
1112 1112
1113 1113
1114 void TestParserSyncWithFlags(i::Handle<i::String> source, 1114 void TestParserSyncWithFlags(i::Handle<i::String> source,
1115 i::EnumSet<ParserFlag> flags) { 1115 i::EnumSet<ParserFlag> flags,
1116 bool assert_success,
ulan 2014/02/05 15:00:10 Maybe enum is better than two flags? Looks like th
marja 2014/02/05 15:28:12 Done.
1117 bool assert_error) {
1116 i::Isolate* isolate = CcTest::i_isolate(); 1118 i::Isolate* isolate = CcTest::i_isolate();
1117 i::Factory* factory = isolate->factory(); 1119 i::Factory* factory = isolate->factory();
1118 1120
1119 uintptr_t stack_limit = isolate->stack_guard()->real_climit(); 1121 uintptr_t stack_limit = isolate->stack_guard()->real_climit();
1120 1122
1121 // Preparse the data. 1123 // Preparse the data.
1122 i::CompleteParserRecorder log; 1124 i::CompleteParserRecorder log;
1123 { 1125 {
1124 i::Scanner scanner(isolate->unicode_cache()); 1126 i::Scanner scanner(isolate->unicode_cache());
1125 i::GenericStringUtf16CharacterStream stream(source, 0, source->length()); 1127 i::GenericStringUtf16CharacterStream stream(source, 0, source->length());
(...skipping 21 matching lines...) Expand all
1147 if (function == NULL) { 1149 if (function == NULL) {
1148 // Extract exception from the parser. 1150 // Extract exception from the parser.
1149 CHECK(isolate->has_pending_exception()); 1151 CHECK(isolate->has_pending_exception());
1150 i::MaybeObject* maybe_object = isolate->pending_exception(); 1152 i::MaybeObject* maybe_object = isolate->pending_exception();
1151 i::JSObject* exception = NULL; 1153 i::JSObject* exception = NULL;
1152 CHECK(maybe_object->To(&exception)); 1154 CHECK(maybe_object->To(&exception));
1153 i::Handle<i::JSObject> exception_handle(exception); 1155 i::Handle<i::JSObject> exception_handle(exception);
1154 i::Handle<i::String> message_string = 1156 i::Handle<i::String> message_string =
1155 i::Handle<i::String>::cast(i::GetProperty(exception_handle, "message")); 1157 i::Handle<i::String>::cast(i::GetProperty(exception_handle, "message"));
1156 1158
1159 if (assert_success) {
1160 i::OS::Print(
1161 "Parser failed on:\n"
1162 "\t%s\n"
1163 "with error:\n"
1164 "\t%s\n"
1165 "However, we expected no error.",
1166 source->ToCString().get(), message_string->ToCString().get());
1167 CHECK(false);
1168 }
1169
1157 if (!data.has_error()) { 1170 if (!data.has_error()) {
1158 i::OS::Print( 1171 i::OS::Print(
1159 "Parser failed on:\n" 1172 "Parser failed on:\n"
1160 "\t%s\n" 1173 "\t%s\n"
1161 "with error:\n" 1174 "with error:\n"
1162 "\t%s\n" 1175 "\t%s\n"
1163 "However, the preparser succeeded", 1176 "However, the preparser succeeded",
1164 source->ToCString().get(), message_string->ToCString().get()); 1177 source->ToCString().get(), message_string->ToCString().get());
1165 CHECK(false); 1178 CHECK(false);
1166 } 1179 }
(...skipping 13 matching lines...) Expand all
1180 } 1193 }
1181 } else if (data.has_error()) { 1194 } else if (data.has_error()) {
1182 i::OS::Print( 1195 i::OS::Print(
1183 "Preparser failed on:\n" 1196 "Preparser failed on:\n"
1184 "\t%s\n" 1197 "\t%s\n"
1185 "with error:\n" 1198 "with error:\n"
1186 "\t%s\n" 1199 "\t%s\n"
1187 "However, the parser succeeded", 1200 "However, the parser succeeded",
1188 source->ToCString().get(), FormatMessage(&data)->ToCString().get()); 1201 source->ToCString().get(), FormatMessage(&data)->ToCString().get());
1189 CHECK(false); 1202 CHECK(false);
1203 } else if (assert_error) {
1204 i::OS::Print(
1205 "Expected error on:\n"
1206 "\t%s\n"
1207 "However, parser and preparser succeeded",
1208 source->ToCString().get());
1209 CHECK(false);
1190 } 1210 }
1191 } 1211 }
1192 1212
1193 1213
1194 void TestParserSync(const char* source, 1214 void TestParserSync(const char* source,
1195 const ParserFlag* flag_list, 1215 const ParserFlag* flag_list,
1196 size_t flag_list_length) { 1216 size_t flag_list_length,
1217 bool assert_success = false,
1218 bool assert_error = false) {
1197 i::Handle<i::String> str = 1219 i::Handle<i::String> str =
1198 CcTest::i_isolate()->factory()->NewStringFromAscii(i::CStrVector(source)); 1220 CcTest::i_isolate()->factory()->NewStringFromAscii(i::CStrVector(source));
1199 for (int bits = 0; bits < (1 << flag_list_length); bits++) { 1221 for (int bits = 0; bits < (1 << flag_list_length); bits++) {
1200 i::EnumSet<ParserFlag> flags; 1222 i::EnumSet<ParserFlag> flags;
1201 for (size_t flag_index = 0; flag_index < flag_list_length; flag_index++) { 1223 for (size_t flag_index = 0; flag_index < flag_list_length; flag_index++) {
1202 if ((bits & (1 << flag_index)) != 0) flags.Add(flag_list[flag_index]); 1224 if ((bits & (1 << flag_index)) != 0) flags.Add(flag_list[flag_index]);
1203 } 1225 }
1204 TestParserSyncWithFlags(str, flags); 1226 TestParserSyncWithFlags(str, flags, assert_success, assert_error);
1205 } 1227 }
1206 } 1228 }
1207 1229
1208 1230
1209 TEST(ParserSync) { 1231 TEST(ParserSync) {
1210 const char* context_data[][2] = { 1232 const char* context_data[][2] = {
1211 { "", "" }, 1233 { "", "" },
1212 { "{", "}" }, 1234 { "{", "}" },
1213 { "if (true) ", " else {}" }, 1235 { "if (true) ", " else {}" },
1214 { "if (true) {} else ", "" }, 1236 { "if (true) {} else ", "" },
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1340 " }; \n" 1362 " }; \n"
1341 "}; \n"; 1363 "}; \n";
1342 v8::Script::Compile(v8::String::NewFromUtf8(CcTest::isolate(), script)); 1364 v8::Script::Compile(v8::String::NewFromUtf8(CcTest::isolate(), script));
1343 CHECK(try_catch.HasCaught()); 1365 CHECK(try_catch.HasCaught());
1344 v8::String::Utf8Value exception(try_catch.Exception()); 1366 v8::String::Utf8Value exception(try_catch.Exception());
1345 CHECK_EQ("SyntaxError: Octal literals are not allowed in strict mode.", 1367 CHECK_EQ("SyntaxError: Octal literals are not allowed in strict mode.",
1346 *exception); 1368 *exception);
1347 } 1369 }
1348 1370
1349 1371
1372 void RunParserSyncTest(const char* context_data[][2],
1373 const char* statement_data[],
1374 bool assert_success,
1375 bool assert_error) {
1376 v8::HandleScope handles(CcTest::isolate());
1377 v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate());
1378 v8::Context::Scope context_scope(context);
1379
1380 int marker;
1381 CcTest::i_isolate()->stack_guard()->SetStackLimit(
1382 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
1383
1384 static const ParserFlag flags[] = {
1385 kAllowLazy, kAllowHarmonyScoping, kAllowModules, kAllowGenerators,
1386 kAllowForOf
1387 };
1388 for (int i = 0; context_data[i][0] != NULL; ++i) {
1389 for (int j = 0; statement_data[j] != NULL; ++j) {
1390 int kPrefixLen = i::StrLength(context_data[i][0]);
1391 int kStatementLen = i::StrLength(statement_data[j]);
1392 int kSuffixLen = i::StrLength(context_data[i][1]);
1393 int kProgramSize = kPrefixLen + kStatementLen + kSuffixLen;
1394
1395 // Plug the source code pieces together.
1396 i::ScopedVector<char> program(kProgramSize + 1);
1397 int length = i::OS::SNPrintF(program,
1398 "%s%s%s",
1399 context_data[i][0],
1400 statement_data[j],
1401 context_data[i][1]);
1402 CHECK(length == kProgramSize);
1403 TestParserSync(program.start(),
1404 flags,
1405 ARRAY_SIZE(flags),
1406 assert_success,
1407 assert_error);
1408 }
1409 }
1410 }
1411
1412
1350 TEST(ErrorsEvalAndArguments) { 1413 TEST(ErrorsEvalAndArguments) {
1351 // Tests that both preparsing and parsing produce the right kind of errors for 1414 // Tests that both preparsing and parsing produce the right kind of errors for
1352 // using "eval" and "arguments" as identifiers. Without the strict mode, it's 1415 // using "eval" and "arguments" as identifiers. Without the strict mode, it's
1353 // ok to use "eval" or "arguments" as identifiers. With the strict mode, it 1416 // ok to use "eval" or "arguments" as identifiers. With the strict mode, it
1354 // isn't. 1417 // isn't.
1355 const char* context_data[][2] = { 1418 const char* context_data[][2] = {
1356 { "", "" }, 1419 { "\"use strict\";", "" },
1357 { "\"use strict\";", "}" },
1358 { "var eval; function test_func() {", "}"},
1359 { "var eval; function test_func() {\"use strict\"; ", "}"}, 1420 { "var eval; function test_func() {\"use strict\"; ", "}"},
1360 { NULL, NULL } 1421 { NULL, NULL }
1361 }; 1422 };
1362 1423
1363 const char* statement_data[] = { 1424 const char* statement_data[] = {
1364 "var eval;", 1425 "var eval;",
1365 "var arguments", 1426 "var arguments",
1366 "var foo, eval;", 1427 "var foo, eval;",
1367 "var foo, arguments;", 1428 "var foo, arguments;",
1368 "try { } catch (eval) { }", 1429 "try { } catch (eval) { }",
1369 "try { } catch (arguments) { }", 1430 "try { } catch (arguments) { }",
1370 "function eval() { }", 1431 "function eval() { }",
1371 "function arguments() { }", 1432 "function arguments() { }",
1372 "function foo(eval) { }", 1433 "function foo(eval) { }",
1373 "function foo(arguments) { }", 1434 "function foo(arguments) { }",
1374 "function foo(bar, eval) { }", 1435 "function foo(bar, eval) { }",
1375 "function foo(bar, arguments) { }", 1436 "function foo(bar, arguments) { }",
1376 "eval = 1;", 1437 "eval = 1;",
1377 "arguments = 1;", 1438 "arguments = 1;",
1378 "var foo = eval = 1;", 1439 "var foo = eval = 1;",
1379 "var foo = arguments = 1;", 1440 "var foo = arguments = 1;",
1380 "++eval;", 1441 "++eval;",
1381 "++arguments;", 1442 "++arguments;",
1382 "eval++;", 1443 "eval++;",
1383 "arguments++;", 1444 "arguments++;",
1384 NULL 1445 NULL
1385 }; 1446 };
1386 1447
1387 v8::HandleScope handles(CcTest::isolate()); 1448 RunParserSyncTest(context_data, statement_data, false, true);
1388 v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate());
1389 v8::Context::Scope context_scope(context);
1390
1391 int marker;
1392 CcTest::i_isolate()->stack_guard()->SetStackLimit(
1393 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
1394
1395 static const ParserFlag flags[] = {
1396 kAllowLazy, kAllowHarmonyScoping, kAllowModules, kAllowGenerators,
1397 kAllowForOf
1398 };
1399 for (int i = 0; context_data[i][0] != NULL; ++i) {
1400 for (int j = 0; statement_data[j] != NULL; ++j) {
1401 int kPrefixLen = i::StrLength(context_data[i][0]);
1402 int kStatementLen = i::StrLength(statement_data[j]);
1403 int kSuffixLen = i::StrLength(context_data[i][1]);
1404 int kProgramSize = kPrefixLen + kStatementLen + kSuffixLen;
1405
1406 // Plug the source code pieces together.
1407 i::ScopedVector<char> program(kProgramSize + 1);
1408 int length = i::OS::SNPrintF(program,
1409 "%s%s%s",
1410 context_data[i][0],
1411 statement_data[j],
1412 context_data[i][1]);
1413 CHECK(length == kProgramSize);
1414 TestParserSync(program.start(), flags, ARRAY_SIZE(flags));
1415 }
1416 }
1417 } 1449 }
1418 1450
1419 1451
1452 TEST(NoErrorsEvalAndArgumentsClassic) {
1453 // Tests that both preparsing and parsing accept "eval" and "arguments" as
1454 // identifiers when needed.
1455 const char* context_data[][2] = {
1456 { "", "" },
1457 { "function test_func() {", "}"},
1458 { NULL, NULL }
1459 };
1460
1461 const char* statement_data[] = {
1462 "var eval;",
1463 "var arguments",
1464 "var foo, eval;",
1465 "var foo, arguments;",
1466 "try { } catch (eval) { }",
1467 "try { } catch (arguments) { }",
1468 "function eval() { }",
1469 "function arguments() { }",
1470 "function foo(eval) { }",
1471 "function foo(arguments) { }",
1472 "function foo(bar, eval) { }",
1473 "function foo(bar, arguments) { }",
1474 "eval = 1;",
1475 "arguments = 1;",
1476 "var foo = eval = 1;",
1477 "var foo = arguments = 1;",
1478 "++eval;",
1479 "++arguments;",
1480 "eval++;",
1481 "arguments++;",
1482 NULL
1483 };
1484
1485 RunParserSyncTest(context_data, statement_data, true, false);
1486 }
1487
1488
1489 TEST(NoErrorsEvalAndArgumentsStrict) {
1490 const char* context_data[][2] = {
1491 { "\"use strict\";", "" },
1492 { "function test_func() { \"use strict\";", "}" },
1493 { NULL, NULL }
1494 };
1495
1496 const char* statement_data[] = {
1497 "eval;",
1498 "arguments;",
1499 "var foo = eval;",
1500 "var foo = arguments;",
1501 "var foo = { eval: 1 };",
1502 "var foo = { arguments: 1 };",
1503 "var foo = { }; foo.eval = {};",
1504 "var foo = { }; foo.arguments = {};",
1505 NULL
1506 };
1507
1508 RunParserSyncTest(context_data, statement_data, true, false);
1509 }
1510
1511
1420 TEST(ErrorsFutureStrictReservedWords) { 1512 TEST(ErrorsFutureStrictReservedWords) {
1421 // Tests that both preparsing and parsing produce the right kind of errors for 1513 // Tests that both preparsing and parsing produce the right kind of errors for
1422 // using future strict reserved words as identifiers. Without the strict mode, 1514 // using future strict reserved words as identifiers. Without the strict mode,
1423 // it's ok to use future strict reserved words as identifiers. With the strict 1515 // it's ok to use future strict reserved words as identifiers. With the strict
1424 // mode, it isn't. 1516 // mode, it isn't.
1425 const char* context_data[][2] = { 1517 const char* context_data[][2] = {
1426 { "", "" }, 1518 { "\"use strict\";", "" },
1427 { "\"use strict\";", "}" }, 1519 { "function test_func() {\"use strict\"; ", "}"},
1428 { "var eval; function test_func() {", "}"},
1429 { "var eval; function test_func() {\"use strict\"; ", "}"},
1430 { NULL, NULL } 1520 { NULL, NULL }
1431 }; 1521 };
1432 1522
1433 const char* statement_data[] = { 1523 const char* statement_data[] = {
1434 "var interface;", 1524 "var interface;",
1435 "var foo, interface;", 1525 "var foo, interface;",
1436 "try { } catch (interface) { }", 1526 "try { } catch (interface) { }",
1437 "function interface() { }", 1527 "function interface() { }",
1438 "function foo(interface) { }", 1528 "function foo(interface) { }",
1439 "function foo(bar, interface) { }", 1529 "function foo(bar, interface) { }",
1440 "interface = 1;", 1530 "interface = 1;",
1441 "var foo = interface = 1;", 1531 "var foo = interface = 1;",
1442 "++interface;", 1532 "++interface;",
1443 "interface++;", 1533 "interface++;",
1444 NULL 1534 NULL
1445 }; 1535 };
1446 1536
1447 v8::HandleScope handles(CcTest::isolate()); 1537 RunParserSyncTest(context_data, statement_data, false, true);
1448 v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate());
1449 v8::Context::Scope context_scope(context);
1450
1451 int marker;
1452 CcTest::i_isolate()->stack_guard()->SetStackLimit(
1453 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
1454
1455 static const ParserFlag flags[] = {
1456 kAllowLazy, kAllowHarmonyScoping, kAllowModules, kAllowGenerators,
1457 kAllowForOf
1458 };
1459 for (int i = 0; context_data[i][0] != NULL; ++i) {
1460 for (int j = 0; statement_data[j] != NULL; ++j) {
1461 int kPrefixLen = i::StrLength(context_data[i][0]);
1462 int kStatementLen = i::StrLength(statement_data[j]);
1463 int kSuffixLen = i::StrLength(context_data[i][1]);
1464 int kProgramSize = kPrefixLen + kStatementLen + kSuffixLen;
1465
1466 // Plug the source code pieces together.
1467 i::ScopedVector<char> program(kProgramSize + 1);
1468 int length = i::OS::SNPrintF(program,
1469 "%s%s%s",
1470 context_data[i][0],
1471 statement_data[j],
1472 context_data[i][1]);
1473 CHECK(length == kProgramSize);
1474 TestParserSync(program.start(), flags, ARRAY_SIZE(flags));
1475 }
1476 }
1477 } 1538 }
1478 1539
1479 1540
1541 TEST(NoErrorsFutureStrictReservedWords) {
1542 const char* context_data[][2] = {
1543 { "", "" },
1544 { "function test_func() {", "}"},
1545 { NULL, NULL }
1546 };
1547
1548 const char* statement_data[] = {
1549 "var interface;",
1550 "var foo, interface;",
1551 "try { } catch (interface) { }",
1552 "function interface() { }",
1553 "function foo(interface) { }",
1554 "function foo(bar, interface) { }",
1555 "interface = 1;",
1556 "var foo = interface = 1;",
1557 "++interface;",
1558 "interface++;",
1559 NULL
1560 };
1561
1562 RunParserSyncTest(context_data, statement_data, true, false);
1563 }
1564
1565
1480 TEST(ErrorsReservedWords) { 1566 TEST(ErrorsReservedWords) {
1481 // Tests that both preparsing and parsing produce the right kind of errors for 1567 // Tests that both preparsing and parsing produce the right kind of errors for
1482 // using future reserved words as identifiers. These tests don't depend on the 1568 // using future reserved words as identifiers. These tests don't depend on the
1483 // strict mode. 1569 // strict mode.
1484 const char* context_data[][2] = { 1570 const char* context_data[][2] = {
1485 { "", "" }, 1571 { "", "" },
1486 { "\"use strict\";", "}" }, 1572 { "\"use strict\";", "" },
1487 { "var eval; function test_func() {", "}"}, 1573 { "var eval; function test_func() {", "}"},
1488 { "var eval; function test_func() {\"use strict\"; ", "}"}, 1574 { "var eval; function test_func() {\"use strict\"; ", "}"},
1489 { NULL, NULL } 1575 { NULL, NULL }
1490 }; 1576 };
1491 1577
1492 const char* statement_data[] = { 1578 const char* statement_data[] = {
1493 "var super;", 1579 "var super;",
1494 "var foo, super;", 1580 "var foo, super;",
1495 "try { } catch (super) { }", 1581 "try { } catch (super) { }",
1496 "function super() { }", 1582 "function super() { }",
1497 "function foo(super) { }", 1583 "function foo(super) { }",
1498 "function foo(bar, super) { }", 1584 "function foo(bar, super) { }",
1499 "super = 1;", 1585 "super = 1;",
1500 "var foo = super = 1;", 1586 "var foo = super = 1;",
1501 "++super;", 1587 "++super;",
1502 "super++;", 1588 "super++;",
1503 "function foo super", 1589 "function foo super",
1504 NULL 1590 NULL
1505 }; 1591 };
1506 1592
1507 v8::HandleScope handles(CcTest::isolate()); 1593 RunParserSyncTest(context_data, statement_data, false, true);
1508 v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate());
1509 v8::Context::Scope context_scope(context);
1510
1511 int marker;
1512 CcTest::i_isolate()->stack_guard()->SetStackLimit(
1513 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
1514
1515 static const ParserFlag flags[] = {
1516 kAllowLazy, kAllowHarmonyScoping, kAllowModules, kAllowGenerators,
1517 kAllowForOf
1518 };
1519 for (int i = 0; context_data[i][0] != NULL; ++i) {
1520 for (int j = 0; statement_data[j] != NULL; ++j) {
1521 int kPrefixLen = i::StrLength(context_data[i][0]);
1522 int kStatementLen = i::StrLength(statement_data[j]);
1523 int kSuffixLen = i::StrLength(context_data[i][1]);
1524 int kProgramSize = kPrefixLen + kStatementLen + kSuffixLen;
1525
1526 // Plug the source code pieces together.
1527 i::ScopedVector<char> program(kProgramSize + 1);
1528 int length = i::OS::SNPrintF(program,
1529 "%s%s%s",
1530 context_data[i][0],
1531 statement_data[j],
1532 context_data[i][1]);
1533 CHECK(length == kProgramSize);
1534 TestParserSync(program.start(), flags, ARRAY_SIZE(flags));
1535 }
1536 }
1537 } 1594 }
1538 1595
1539 1596
1540 TEST(ErrorsYield) { 1597 TEST(NoErrorsYieldClassic) {
1541 // Tests that both preparsing and parsing produce the right kind of errors for 1598 // In classic mode, it's okay to use "yield" as identifier, *except* inside a
1542 // using yield as identifier. In non-strict mode, it's okay to use "yield" as 1599 // generator (see next test).
1543 // an identifier, *except* inside a generator function. In strict mode, it's
1544 // never okay.
1545 const char* context_data[][2] = { 1600 const char* context_data[][2] = {
1546 { "", "" }, 1601 { "", "" },
1547 { "\"use strict\";", "}" },
1548 { "var eval; function test_func() {", "}"},
1549 { "var eval; function test_func() {\"use strict\"; ", "}"},
1550 { "function is_not_gen() {", "}" }, 1602 { "function is_not_gen() {", "}" },
1551 { "function * is_gen() {", "}" },
1552 { "\"use strict\"; function is_not_gen() {", "}" },
1553 { "\"use strict\"; function * is_gen() {", "}" },
1554 { NULL, NULL } 1603 { NULL, NULL }
1555 }; 1604 };
1556 1605
1606 const char* statement_data[] = {
1607 "var yield;",
1608 "var foo, yield;",
1609 "try { } catch (yield) { }",
1610 "function yield() { }",
1611 "function foo(yield) { }",
1612 "function foo(bar, yield) { }",
1613 "yield = 1;",
1614 "var foo = yield = 1;",
1615 "++yield;",
1616 "yield++;",
1617 NULL
1618 };
1619
1620 RunParserSyncTest(context_data, statement_data, true, false);
1621 }
1622
1623
1624 TEST(ErrorsYieldClassicGenerator) {
1625 const char* context_data[][2] = {
1626 { "function * is_gen() {", "}" },
1627 { NULL, NULL }
1628 };
1629
1630 const char* statement_data[] = {
1631 "var yield;",
1632 "var foo, yield;",
1633 "try { } catch (yield) { }",
1634 "function yield() { }",
1635 // BUG: These should not be allowed, but they are (if kAllowGenerators is
1636 // set)
1637 // "function foo(yield) { }",
1638 // "function foo(bar, yield) { }",
1639 "yield = 1;",
1640 "var foo = yield = 1;",
1641 "++yield;",
1642 "yield++;",
1643 NULL
1644 };
1645
1646 // If generators are not allowed, the error will be produced at the '*' token,
1647 // so this test works both with and without the kAllowGenerators flag.
1648 RunParserSyncTest(context_data, statement_data, false, true);
1649 }
1650
1651
1652 TEST(ErrorsYieldStrict) {
1653 const char* context_data[][2] = {
1654 { "\"use strict\";", "" },
1655 { "\"use strict\"; function is_not_gen() {", "}" },
1656 { "function test_func() {\"use strict\"; ", "}"},
1657 { NULL, NULL }
1658 };
1659
1557 const char* statement_data[] = { 1660 const char* statement_data[] = {
1558 "var yield;", 1661 "var yield;",
1559 "var foo, yield;", 1662 "var foo, yield;",
1560 "try { } catch (yield) { }", 1663 "try { } catch (yield) { }",
1561 "function yield() { }", 1664 "function yield() { }",
1562 "function foo(yield) { }", 1665 "function foo(yield) { }",
1563 "function foo(bar, yield) { }", 1666 "function foo(bar, yield) { }",
1564 "yield = 1;", 1667 "yield = 1;",
1565 "var foo = yield = 1;", 1668 "var foo = yield = 1;",
1566 "++yield;", 1669 "++yield;",
1567 "yield++;", 1670 "yield++;",
1671 NULL
1672 };
1673
1674 RunParserSyncTest(context_data, statement_data, false, true);
1675 }
1676
1677
1678 TEST(ErrorsYield) {
1679 const char* context_data[][2] = {
1680 { "function * is_gen() {", "}" },
1681 { NULL, NULL }
1682 };
1683
1684 const char* statement_data[] = {
1568 "yield 2;", // this is legal inside generator 1685 "yield 2;", // this is legal inside generator
1569 "yield * 2;", // this is legal inside generator 1686 "yield * 2;", // this is legal inside generator
1570 NULL 1687 NULL
1571 }; 1688 };
1572 1689
1573 v8::HandleScope handles(CcTest::isolate()); 1690 // Here we cannot assert that there is no error, since there will be without
1574 v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate()); 1691 // the kAllowGenerators flag. However, we test that Parser and PreParser err
1575 v8::Context::Scope context_scope(context); 1692 // the same way.
1576 1693 RunParserSyncTest(context_data, statement_data, false, false);
1577 int marker;
1578 CcTest::i_isolate()->stack_guard()->SetStackLimit(
1579 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
1580
1581 static const ParserFlag flags[] = {
1582 kAllowLazy, kAllowHarmonyScoping, kAllowModules, kAllowGenerators,
1583 kAllowForOf
1584 };
1585 for (int i = 0; context_data[i][0] != NULL; ++i) {
1586 for (int j = 0; statement_data[j] != NULL; ++j) {
1587 int kPrefixLen = i::StrLength(context_data[i][0]);
1588 int kStatementLen = i::StrLength(statement_data[j]);
1589 int kSuffixLen = i::StrLength(context_data[i][1]);
1590 int kProgramSize = kPrefixLen + kStatementLen + kSuffixLen;
1591
1592 // Plug the source code pieces together.
1593 i::ScopedVector<char> program(kProgramSize + 1);
1594 int length = i::OS::SNPrintF(program,
1595 "%s%s%s",
1596 context_data[i][0],
1597 statement_data[j],
1598 context_data[i][1]);
1599 CHECK(length == kProgramSize);
1600 TestParserSync(program.start(), flags, ARRAY_SIZE(flags));
1601 }
1602 }
1603 } 1694 }
1604 1695
1605 1696
1606 TEST(ErrorsNameOfStrictFunction) { 1697 TEST(ErrorsNameOfStrictFunction) {
1607 // Tests that illegal tokens as names of a strict function produce the correct 1698 // Tests that illegal tokens as names of a strict function produce the correct
1608 // errors. 1699 // errors.
1700 const char* context_data[][2] = {
1701 { "", ""},
1702 { "\"use strict\";", ""},
1703 { NULL, NULL }
1704 };
1705
1609 const char* statement_data[] = { 1706 const char* statement_data[] = {
1610 "function eval() { }", // legal 1707 "function eval() {\"use strict\";}",
1611 "function eval() {\"use strict\";}", // illegal 1708 "function arguments() {\"use strict\";}",
1612 "function arguments() { }", // legal 1709 "function interface() {\"use strict\";}",
1613 "function arguments() {\"use strict\";}", // illegal 1710 "function yield() {\"use strict\";}",
1614 // Future reserved words are always illegal 1711 // Future reserved words are always illegal
1615 "function super() { }", // illegal 1712 "function super() { }",
1616 "function super() {\"use strict\";}", // illegal 1713 "function super() {\"use strict\";}",
1617 "function interface() { }", // legal
1618 "function interface() {\"use strict\";}", // illegal
1619 "function yield() { }", // legal
1620 "function yield() {\"use strict\";}", // illegal
1621 NULL 1714 NULL
1622 }; 1715 };
1623 1716
1624 v8::HandleScope handles(CcTest::isolate()); 1717 RunParserSyncTest(context_data, statement_data, false, true);
1625 v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate());
1626 v8::Context::Scope context_scope(context);
1627
1628 int marker;
1629 CcTest::i_isolate()->stack_guard()->SetStackLimit(
1630 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
1631
1632 static const ParserFlag flags[] = {
1633 kAllowLazy, kAllowHarmonyScoping, kAllowModules, kAllowGenerators,
1634 kAllowForOf
1635 };
1636 for (int j = 0; statement_data[j] != NULL; ++j) {
1637 TestParserSync(statement_data[j], flags, ARRAY_SIZE(flags));
1638 }
1639 } 1718 }
1640 1719
1641 1720
1642 TEST(ErrorsIllegalWordsAsLabels) { 1721 TEST(NoErrorsNameOfStrictFunction) {
1722 const char* context_data[][2] = {
1723 { "", ""},
1724 { NULL, NULL }
1725 };
1726
1727 const char* statement_data[] = {
1728 "function eval() { }",
1729 "function arguments() { }",
1730 "function interface() { }",
1731 "function yield() { }",
1732 NULL
1733 };
1734
1735 RunParserSyncTest(context_data, statement_data, true, false);
1736 }
1737
1738
1739
1740 TEST(ErrorsIllegalWordsAsLabelsClassic) {
1643 // Tests that illegal tokens as labels produce the correct errors. 1741 // Tests that illegal tokens as labels produce the correct errors.
1644 const char* context_data[][2] = { 1742 const char* context_data[][2] = {
1645 { "", "" }, 1743 { "", ""},
1646 { "\"use strict\";", "}" }, 1744 { "function test_func() {", "}" },
1745 { NULL, NULL }
1746 };
1747
1748 const char* statement_data[] = {
1749 "super: while(true) { break super; }",
1750 NULL
1751 };
1752
1753 RunParserSyncTest(context_data, statement_data, false, true);
1754 }
1755
1756
1757 TEST(ErrorsIllegalWordsAsLabelsStrict) {
1758 // Tests that illegal tokens as labels produce the correct errors.
1759 const char* context_data[][2] = {
1760 { "\"use strict\";", "" },
1761 { "function test_func() {\"use strict\"; ", "}"},
1762 { NULL, NULL }
1763 };
1764
1765 const char* statement_data[] = {
1766 "super: while(true) { break super; }",
1767 "interface: while(true) { break interface; }",
1768 "yield: while(true) { break yield; }",
1769 NULL
1770 };
1771
1772 RunParserSyncTest(context_data, statement_data, false, true);
1773 }
1774
1775
1776 TEST(NoErrorsIllegalWordsAsLabels) {
1777 // Using eval and arguments as labels is legal even in strict mode.
1778 const char* context_data[][2] = {
1779 { "", ""},
1780 { "function test_func() {", "}" },
1781 { "\"use strict\";", "" },
1782 { "\"use strict\"; function test_func() {", "}" },
1647 { NULL, NULL } 1783 { NULL, NULL }
1648 }; 1784 };
1649 1785
1650 const char* statement_data[] = { 1786 const char* statement_data[] = {
1651 "mylabel: while(true) { break mylabel; }", 1787 "mylabel: while(true) { break mylabel; }",
1652 "eval: while(true) { break eval; }", 1788 "eval: while(true) { break eval; }",
1653 "arguments: while(true) { break arguments; }", 1789 "arguments: while(true) { break arguments; }",
1654 "super: while(true) { break super; }", // always illegal
1655 "interface: while(true) { break interface; }",
1656 "yield: while(true) { break yield; }",
1657 NULL 1790 NULL
1658 }; 1791 };
1659 1792
1660 v8::HandleScope handles(CcTest::isolate()); 1793 RunParserSyncTest(context_data, statement_data, true, false);
1661 v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate());
1662 v8::Context::Scope context_scope(context);
1663
1664 int marker;
1665 CcTest::i_isolate()->stack_guard()->SetStackLimit(
1666 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
1667
1668 static const ParserFlag flags[] = {
1669 kAllowLazy, kAllowHarmonyScoping, kAllowModules, kAllowGenerators,
1670 kAllowForOf
1671 };
1672 for (int i = 0; context_data[i][0] != NULL; ++i) {
1673 for (int j = 0; statement_data[j] != NULL; ++j) {
1674 int kPrefixLen = i::StrLength(context_data[i][0]);
1675 int kStatementLen = i::StrLength(statement_data[j]);
1676 int kSuffixLen = i::StrLength(context_data[i][1]);
1677 int kProgramSize = kPrefixLen + kStatementLen + kSuffixLen;
1678
1679 // Plug the source code pieces together.
1680 i::ScopedVector<char> program(kProgramSize + 1);
1681 int length = i::OS::SNPrintF(program,
1682 "%s%s%s",
1683 context_data[i][0],
1684 statement_data[j],
1685 context_data[i][1]);
1686 CHECK(length == kProgramSize);
1687 TestParserSync(program.start(), flags, ARRAY_SIZE(flags));
1688 }
1689 }
1690 } 1794 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698