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