| 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 |