| 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 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 237 CHECK(error_preparse->HasError()); | 237 CHECK(error_preparse->HasError()); |
| 238 i::ScriptDataImpl *pre_impl = | 238 i::ScriptDataImpl *pre_impl = |
| 239 reinterpret_cast<i::ScriptDataImpl*>(error_preparse); | 239 reinterpret_cast<i::ScriptDataImpl*>(error_preparse); |
| 240 i::Scanner::Location error_location = | 240 i::Scanner::Location error_location = |
| 241 pre_impl->MessageLocation(); | 241 pre_impl->MessageLocation(); |
| 242 // Error is at "z" in source, location 10..11. | 242 // Error is at "z" in source, location 10..11. |
| 243 CHECK_EQ(10, error_location.beg_pos); | 243 CHECK_EQ(10, error_location.beg_pos); |
| 244 CHECK_EQ(11, error_location.end_pos); | 244 CHECK_EQ(11, error_location.end_pos); |
| 245 // Should not crash. | 245 // Should not crash. |
| 246 const char* message = pre_impl->BuildMessage(); | 246 const char* message = pre_impl->BuildMessage(); |
| 247 pre_impl->BuildArgs(); | 247 i::Vector<const char*> args = pre_impl->BuildArgs(); |
| 248 CHECK_GT(strlen(message), 0); | 248 CHECK_GT(strlen(message), 0); |
| 249 args.Dispose(); |
| 250 i::DeleteArray(message); |
| 251 delete error_preparse; |
| 249 } | 252 } |
| 250 | 253 |
| 251 | 254 |
| 252 TEST(StandAlonePreParser) { | 255 TEST(StandAlonePreParser) { |
| 253 v8::V8::Initialize(); | 256 v8::V8::Initialize(); |
| 254 | 257 |
| 255 int marker; | 258 int marker; |
| 256 CcTest::i_isolate()->stack_guard()->SetStackLimit( | 259 CcTest::i_isolate()->stack_guard()->SetStackLimit( |
| 257 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); | 260 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); |
| 258 | 261 |
| (...skipping 753 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1012 | 1015 |
| 1013 for (int i = 0; source_data[i].outer_prefix; i++) { | 1016 for (int i = 0; source_data[i].outer_prefix; i++) { |
| 1014 int kPrefixLen = Utf8LengthHelper(source_data[i].outer_prefix); | 1017 int kPrefixLen = Utf8LengthHelper(source_data[i].outer_prefix); |
| 1015 int kInnerLen = Utf8LengthHelper(source_data[i].inner_source); | 1018 int kInnerLen = Utf8LengthHelper(source_data[i].inner_source); |
| 1016 int kSuffixLen = Utf8LengthHelper(source_data[i].outer_suffix); | 1019 int kSuffixLen = Utf8LengthHelper(source_data[i].outer_suffix); |
| 1017 int kPrefixByteLen = i::StrLength(source_data[i].outer_prefix); | 1020 int kPrefixByteLen = i::StrLength(source_data[i].outer_prefix); |
| 1018 int kInnerByteLen = i::StrLength(source_data[i].inner_source); | 1021 int kInnerByteLen = i::StrLength(source_data[i].inner_source); |
| 1019 int kSuffixByteLen = i::StrLength(source_data[i].outer_suffix); | 1022 int kSuffixByteLen = i::StrLength(source_data[i].outer_suffix); |
| 1020 int kProgramSize = kPrefixLen + kInnerLen + kSuffixLen; | 1023 int kProgramSize = kPrefixLen + kInnerLen + kSuffixLen; |
| 1021 int kProgramByteSize = kPrefixByteLen + kInnerByteLen + kSuffixByteLen; | 1024 int kProgramByteSize = kPrefixByteLen + kInnerByteLen + kSuffixByteLen; |
| 1022 i::Vector<char> program = i::Vector<char>::New(kProgramByteSize + 1); | 1025 i::ScopedVector<char> program(kProgramByteSize + 1); |
| 1023 i::OS::SNPrintF(program, "%s%s%s", | 1026 i::OS::SNPrintF(program, "%s%s%s", |
| 1024 source_data[i].outer_prefix, | 1027 source_data[i].outer_prefix, |
| 1025 source_data[i].inner_source, | 1028 source_data[i].inner_source, |
| 1026 source_data[i].outer_suffix); | 1029 source_data[i].outer_suffix); |
| 1027 | 1030 |
| 1028 // Parse program source. | 1031 // Parse program source. |
| 1029 i::Handle<i::String> source( | 1032 i::Handle<i::String> source( |
| 1030 factory->NewStringFromUtf8(i::CStrVector(program.start()))); | 1033 factory->NewStringFromUtf8(i::CStrVector(program.start()))); |
| 1031 CHECK_EQ(source->length(), kProgramSize); | 1034 CHECK_EQ(source->length(), kProgramSize); |
| 1032 i::Handle<i::Script> script = factory->NewScript(source); | 1035 i::Handle<i::Script> script = factory->NewScript(source); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1092 kAllowLazy, | 1095 kAllowLazy, |
| 1093 kAllowNativesSyntax, | 1096 kAllowNativesSyntax, |
| 1094 kAllowHarmonyScoping, | 1097 kAllowHarmonyScoping, |
| 1095 kAllowModules, | 1098 kAllowModules, |
| 1096 kAllowGenerators, | 1099 kAllowGenerators, |
| 1097 kAllowForOf, | 1100 kAllowForOf, |
| 1098 kAllowHarmonyNumericLiterals | 1101 kAllowHarmonyNumericLiterals |
| 1099 }; | 1102 }; |
| 1100 | 1103 |
| 1101 | 1104 |
| 1105 enum ParserSyncTestResult { |
| 1106 kSuccessOrError, |
| 1107 kSuccess, |
| 1108 kError |
| 1109 }; |
| 1110 |
| 1111 |
| 1102 void SetParserFlags(i::ParserBase* parser, i::EnumSet<ParserFlag> flags) { | 1112 void SetParserFlags(i::ParserBase* parser, i::EnumSet<ParserFlag> flags) { |
| 1103 parser->set_allow_lazy(flags.Contains(kAllowLazy)); | 1113 parser->set_allow_lazy(flags.Contains(kAllowLazy)); |
| 1104 parser->set_allow_natives_syntax(flags.Contains(kAllowNativesSyntax)); | 1114 parser->set_allow_natives_syntax(flags.Contains(kAllowNativesSyntax)); |
| 1105 parser->set_allow_harmony_scoping(flags.Contains(kAllowHarmonyScoping)); | 1115 parser->set_allow_harmony_scoping(flags.Contains(kAllowHarmonyScoping)); |
| 1106 parser->set_allow_modules(flags.Contains(kAllowModules)); | 1116 parser->set_allow_modules(flags.Contains(kAllowModules)); |
| 1107 parser->set_allow_generators(flags.Contains(kAllowGenerators)); | 1117 parser->set_allow_generators(flags.Contains(kAllowGenerators)); |
| 1108 parser->set_allow_for_of(flags.Contains(kAllowForOf)); | 1118 parser->set_allow_for_of(flags.Contains(kAllowForOf)); |
| 1109 parser->set_allow_harmony_numeric_literals( | 1119 parser->set_allow_harmony_numeric_literals( |
| 1110 flags.Contains(kAllowHarmonyNumericLiterals)); | 1120 flags.Contains(kAllowHarmonyNumericLiterals)); |
| 1111 } | 1121 } |
| 1112 | 1122 |
| 1113 | 1123 |
| 1114 void TestParserSyncWithFlags(i::Handle<i::String> source, | 1124 void TestParserSyncWithFlags(i::Handle<i::String> source, |
| 1115 i::EnumSet<ParserFlag> flags) { | 1125 i::EnumSet<ParserFlag> flags, |
| 1126 ParserSyncTestResult result) { |
| 1116 i::Isolate* isolate = CcTest::i_isolate(); | 1127 i::Isolate* isolate = CcTest::i_isolate(); |
| 1117 i::Factory* factory = isolate->factory(); | 1128 i::Factory* factory = isolate->factory(); |
| 1118 | 1129 |
| 1119 uintptr_t stack_limit = isolate->stack_guard()->real_climit(); | 1130 uintptr_t stack_limit = isolate->stack_guard()->real_climit(); |
| 1120 | 1131 |
| 1121 // Preparse the data. | 1132 // Preparse the data. |
| 1122 i::CompleteParserRecorder log; | 1133 i::CompleteParserRecorder log; |
| 1123 { | 1134 { |
| 1124 i::Scanner scanner(isolate->unicode_cache()); | 1135 i::Scanner scanner(isolate->unicode_cache()); |
| 1125 i::GenericStringUtf16CharacterStream stream(source, 0, source->length()); | 1136 i::GenericStringUtf16CharacterStream stream(source, 0, source->length()); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1147 if (function == NULL) { | 1158 if (function == NULL) { |
| 1148 // Extract exception from the parser. | 1159 // Extract exception from the parser. |
| 1149 CHECK(isolate->has_pending_exception()); | 1160 CHECK(isolate->has_pending_exception()); |
| 1150 i::MaybeObject* maybe_object = isolate->pending_exception(); | 1161 i::MaybeObject* maybe_object = isolate->pending_exception(); |
| 1151 i::JSObject* exception = NULL; | 1162 i::JSObject* exception = NULL; |
| 1152 CHECK(maybe_object->To(&exception)); | 1163 CHECK(maybe_object->To(&exception)); |
| 1153 i::Handle<i::JSObject> exception_handle(exception); | 1164 i::Handle<i::JSObject> exception_handle(exception); |
| 1154 i::Handle<i::String> message_string = | 1165 i::Handle<i::String> message_string = |
| 1155 i::Handle<i::String>::cast(i::GetProperty(exception_handle, "message")); | 1166 i::Handle<i::String>::cast(i::GetProperty(exception_handle, "message")); |
| 1156 | 1167 |
| 1168 if (result == kSuccess) { |
| 1169 i::OS::Print( |
| 1170 "Parser failed on:\n" |
| 1171 "\t%s\n" |
| 1172 "with error:\n" |
| 1173 "\t%s\n" |
| 1174 "However, we expected no error.", |
| 1175 source->ToCString().get(), message_string->ToCString().get()); |
| 1176 CHECK(false); |
| 1177 } |
| 1178 |
| 1157 if (!data.has_error()) { | 1179 if (!data.has_error()) { |
| 1158 i::OS::Print( | 1180 i::OS::Print( |
| 1159 "Parser failed on:\n" | 1181 "Parser failed on:\n" |
| 1160 "\t%s\n" | 1182 "\t%s\n" |
| 1161 "with error:\n" | 1183 "with error:\n" |
| 1162 "\t%s\n" | 1184 "\t%s\n" |
| 1163 "However, the preparser succeeded", | 1185 "However, the preparser succeeded", |
| 1164 source->ToCString().get(), message_string->ToCString().get()); | 1186 source->ToCString().get(), message_string->ToCString().get()); |
| 1165 CHECK(false); | 1187 CHECK(false); |
| 1166 } | 1188 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1180 } | 1202 } |
| 1181 } else if (data.has_error()) { | 1203 } else if (data.has_error()) { |
| 1182 i::OS::Print( | 1204 i::OS::Print( |
| 1183 "Preparser failed on:\n" | 1205 "Preparser failed on:\n" |
| 1184 "\t%s\n" | 1206 "\t%s\n" |
| 1185 "with error:\n" | 1207 "with error:\n" |
| 1186 "\t%s\n" | 1208 "\t%s\n" |
| 1187 "However, the parser succeeded", | 1209 "However, the parser succeeded", |
| 1188 source->ToCString().get(), FormatMessage(&data)->ToCString().get()); | 1210 source->ToCString().get(), FormatMessage(&data)->ToCString().get()); |
| 1189 CHECK(false); | 1211 CHECK(false); |
| 1212 } else if (result == kError) { |
| 1213 i::OS::Print( |
| 1214 "Expected error on:\n" |
| 1215 "\t%s\n" |
| 1216 "However, parser and preparser succeeded", |
| 1217 source->ToCString().get()); |
| 1218 CHECK(false); |
| 1190 } | 1219 } |
| 1191 } | 1220 } |
| 1192 | 1221 |
| 1193 | 1222 |
| 1194 void TestParserSync(const char* source, | 1223 void TestParserSync(const char* source, |
| 1195 const ParserFlag* flag_list, | 1224 const ParserFlag* flag_list, |
| 1196 size_t flag_list_length) { | 1225 size_t flag_list_length, |
| 1226 ParserSyncTestResult result = kSuccessOrError) { |
| 1197 i::Handle<i::String> str = | 1227 i::Handle<i::String> str = |
| 1198 CcTest::i_isolate()->factory()->NewStringFromAscii(i::CStrVector(source)); | 1228 CcTest::i_isolate()->factory()->NewStringFromAscii(i::CStrVector(source)); |
| 1199 for (int bits = 0; bits < (1 << flag_list_length); bits++) { | 1229 for (int bits = 0; bits < (1 << flag_list_length); bits++) { |
| 1200 i::EnumSet<ParserFlag> flags; | 1230 i::EnumSet<ParserFlag> flags; |
| 1201 for (size_t flag_index = 0; flag_index < flag_list_length; flag_index++) { | 1231 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]); | 1232 if ((bits & (1 << flag_index)) != 0) flags.Add(flag_list[flag_index]); |
| 1203 } | 1233 } |
| 1204 TestParserSyncWithFlags(str, flags); | 1234 TestParserSyncWithFlags(str, flags, result); |
| 1205 } | 1235 } |
| 1206 } | 1236 } |
| 1207 | 1237 |
| 1208 | 1238 |
| 1209 TEST(ParserSync) { | 1239 TEST(ParserSync) { |
| 1210 const char* context_data[][2] = { | 1240 const char* context_data[][2] = { |
| 1211 { "", "" }, | 1241 { "", "" }, |
| 1212 { "{", "}" }, | 1242 { "{", "}" }, |
| 1213 { "if (true) ", " else {}" }, | 1243 { "if (true) ", " else {}" }, |
| 1214 { "if (true) {} else ", "" }, | 1244 { "if (true) {} else ", "" }, |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1338 " b = function() { \n" | 1368 " b = function() { \n" |
| 1339 " 01; \n" | 1369 " 01; \n" |
| 1340 " }; \n" | 1370 " }; \n" |
| 1341 "}; \n"; | 1371 "}; \n"; |
| 1342 v8::Script::Compile(v8::String::NewFromUtf8(CcTest::isolate(), script)); | 1372 v8::Script::Compile(v8::String::NewFromUtf8(CcTest::isolate(), script)); |
| 1343 CHECK(try_catch.HasCaught()); | 1373 CHECK(try_catch.HasCaught()); |
| 1344 v8::String::Utf8Value exception(try_catch.Exception()); | 1374 v8::String::Utf8Value exception(try_catch.Exception()); |
| 1345 CHECK_EQ("SyntaxError: Octal literals are not allowed in strict mode.", | 1375 CHECK_EQ("SyntaxError: Octal literals are not allowed in strict mode.", |
| 1346 *exception); | 1376 *exception); |
| 1347 } | 1377 } |
| 1378 |
| 1379 |
| 1380 void RunParserSyncTest(const char* context_data[][2], |
| 1381 const char* statement_data[], |
| 1382 ParserSyncTestResult result) { |
| 1383 v8::HandleScope handles(CcTest::isolate()); |
| 1384 v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate()); |
| 1385 v8::Context::Scope context_scope(context); |
| 1386 |
| 1387 int marker; |
| 1388 CcTest::i_isolate()->stack_guard()->SetStackLimit( |
| 1389 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); |
| 1390 |
| 1391 static const ParserFlag flags[] = { |
| 1392 kAllowLazy, kAllowHarmonyScoping, kAllowModules, kAllowGenerators, |
| 1393 kAllowForOf |
| 1394 }; |
| 1395 for (int i = 0; context_data[i][0] != NULL; ++i) { |
| 1396 for (int j = 0; statement_data[j] != NULL; ++j) { |
| 1397 int kPrefixLen = i::StrLength(context_data[i][0]); |
| 1398 int kStatementLen = i::StrLength(statement_data[j]); |
| 1399 int kSuffixLen = i::StrLength(context_data[i][1]); |
| 1400 int kProgramSize = kPrefixLen + kStatementLen + kSuffixLen; |
| 1401 |
| 1402 // Plug the source code pieces together. |
| 1403 i::ScopedVector<char> program(kProgramSize + 1); |
| 1404 int length = i::OS::SNPrintF(program, |
| 1405 "%s%s%s", |
| 1406 context_data[i][0], |
| 1407 statement_data[j], |
| 1408 context_data[i][1]); |
| 1409 CHECK(length == kProgramSize); |
| 1410 TestParserSync(program.start(), |
| 1411 flags, |
| 1412 ARRAY_SIZE(flags), |
| 1413 result); |
| 1414 } |
| 1415 } |
| 1416 } |
| 1417 |
| 1418 |
| 1419 TEST(ErrorsEvalAndArguments) { |
| 1420 // Tests that both preparsing and parsing produce the right kind of errors for |
| 1421 // using "eval" and "arguments" as identifiers. Without the strict mode, it's |
| 1422 // ok to use "eval" or "arguments" as identifiers. With the strict mode, it |
| 1423 // isn't. |
| 1424 const char* context_data[][2] = { |
| 1425 { "\"use strict\";", "" }, |
| 1426 { "var eval; function test_func() {\"use strict\"; ", "}"}, |
| 1427 { NULL, NULL } |
| 1428 }; |
| 1429 |
| 1430 const char* statement_data[] = { |
| 1431 "var eval;", |
| 1432 "var arguments", |
| 1433 "var foo, eval;", |
| 1434 "var foo, arguments;", |
| 1435 "try { } catch (eval) { }", |
| 1436 "try { } catch (arguments) { }", |
| 1437 "function eval() { }", |
| 1438 "function arguments() { }", |
| 1439 "function foo(eval) { }", |
| 1440 "function foo(arguments) { }", |
| 1441 "function foo(bar, eval) { }", |
| 1442 "function foo(bar, arguments) { }", |
| 1443 "eval = 1;", |
| 1444 "arguments = 1;", |
| 1445 "var foo = eval = 1;", |
| 1446 "var foo = arguments = 1;", |
| 1447 "++eval;", |
| 1448 "++arguments;", |
| 1449 "eval++;", |
| 1450 "arguments++;", |
| 1451 NULL |
| 1452 }; |
| 1453 |
| 1454 RunParserSyncTest(context_data, statement_data, kError); |
| 1455 } |
| 1456 |
| 1457 |
| 1458 TEST(NoErrorsEvalAndArgumentsClassic) { |
| 1459 // Tests that both preparsing and parsing accept "eval" and "arguments" as |
| 1460 // identifiers when needed. |
| 1461 const char* context_data[][2] = { |
| 1462 { "", "" }, |
| 1463 { "function test_func() {", "}"}, |
| 1464 { NULL, NULL } |
| 1465 }; |
| 1466 |
| 1467 const char* statement_data[] = { |
| 1468 "var eval;", |
| 1469 "var arguments", |
| 1470 "var foo, eval;", |
| 1471 "var foo, arguments;", |
| 1472 "try { } catch (eval) { }", |
| 1473 "try { } catch (arguments) { }", |
| 1474 "function eval() { }", |
| 1475 "function arguments() { }", |
| 1476 "function foo(eval) { }", |
| 1477 "function foo(arguments) { }", |
| 1478 "function foo(bar, eval) { }", |
| 1479 "function foo(bar, arguments) { }", |
| 1480 "eval = 1;", |
| 1481 "arguments = 1;", |
| 1482 "var foo = eval = 1;", |
| 1483 "var foo = arguments = 1;", |
| 1484 "++eval;", |
| 1485 "++arguments;", |
| 1486 "eval++;", |
| 1487 "arguments++;", |
| 1488 NULL |
| 1489 }; |
| 1490 |
| 1491 RunParserSyncTest(context_data, statement_data, kSuccess); |
| 1492 } |
| 1493 |
| 1494 |
| 1495 TEST(NoErrorsEvalAndArgumentsStrict) { |
| 1496 const char* context_data[][2] = { |
| 1497 { "\"use strict\";", "" }, |
| 1498 { "function test_func() { \"use strict\";", "}" }, |
| 1499 { NULL, NULL } |
| 1500 }; |
| 1501 |
| 1502 const char* statement_data[] = { |
| 1503 "eval;", |
| 1504 "arguments;", |
| 1505 "var foo = eval;", |
| 1506 "var foo = arguments;", |
| 1507 "var foo = { eval: 1 };", |
| 1508 "var foo = { arguments: 1 };", |
| 1509 "var foo = { }; foo.eval = {};", |
| 1510 "var foo = { }; foo.arguments = {};", |
| 1511 NULL |
| 1512 }; |
| 1513 |
| 1514 RunParserSyncTest(context_data, statement_data, kSuccess); |
| 1515 } |
| 1516 |
| 1517 |
| 1518 TEST(ErrorsFutureStrictReservedWords) { |
| 1519 // Tests that both preparsing and parsing produce the right kind of errors for |
| 1520 // using future strict reserved words as identifiers. Without the strict mode, |
| 1521 // it's ok to use future strict reserved words as identifiers. With the strict |
| 1522 // mode, it isn't. |
| 1523 const char* context_data[][2] = { |
| 1524 { "\"use strict\";", "" }, |
| 1525 { "function test_func() {\"use strict\"; ", "}"}, |
| 1526 { NULL, NULL } |
| 1527 }; |
| 1528 |
| 1529 const char* statement_data[] = { |
| 1530 "var interface;", |
| 1531 "var foo, interface;", |
| 1532 "try { } catch (interface) { }", |
| 1533 "function interface() { }", |
| 1534 "function foo(interface) { }", |
| 1535 "function foo(bar, interface) { }", |
| 1536 "interface = 1;", |
| 1537 "var foo = interface = 1;", |
| 1538 "++interface;", |
| 1539 "interface++;", |
| 1540 NULL |
| 1541 }; |
| 1542 |
| 1543 RunParserSyncTest(context_data, statement_data, kError); |
| 1544 } |
| 1545 |
| 1546 |
| 1547 TEST(NoErrorsFutureStrictReservedWords) { |
| 1548 const char* context_data[][2] = { |
| 1549 { "", "" }, |
| 1550 { "function test_func() {", "}"}, |
| 1551 { NULL, NULL } |
| 1552 }; |
| 1553 |
| 1554 const char* statement_data[] = { |
| 1555 "var interface;", |
| 1556 "var foo, interface;", |
| 1557 "try { } catch (interface) { }", |
| 1558 "function interface() { }", |
| 1559 "function foo(interface) { }", |
| 1560 "function foo(bar, interface) { }", |
| 1561 "interface = 1;", |
| 1562 "var foo = interface = 1;", |
| 1563 "++interface;", |
| 1564 "interface++;", |
| 1565 NULL |
| 1566 }; |
| 1567 |
| 1568 RunParserSyncTest(context_data, statement_data, kSuccess); |
| 1569 } |
| 1570 |
| 1571 |
| 1572 TEST(ErrorsReservedWords) { |
| 1573 // Tests that both preparsing and parsing produce the right kind of errors for |
| 1574 // using future reserved words as identifiers. These tests don't depend on the |
| 1575 // strict mode. |
| 1576 const char* context_data[][2] = { |
| 1577 { "", "" }, |
| 1578 { "\"use strict\";", "" }, |
| 1579 { "var eval; function test_func() {", "}"}, |
| 1580 { "var eval; function test_func() {\"use strict\"; ", "}"}, |
| 1581 { NULL, NULL } |
| 1582 }; |
| 1583 |
| 1584 const char* statement_data[] = { |
| 1585 "var super;", |
| 1586 "var foo, super;", |
| 1587 "try { } catch (super) { }", |
| 1588 "function super() { }", |
| 1589 "function foo(super) { }", |
| 1590 "function foo(bar, super) { }", |
| 1591 "super = 1;", |
| 1592 "var foo = super = 1;", |
| 1593 "++super;", |
| 1594 "super++;", |
| 1595 "function foo super", |
| 1596 NULL |
| 1597 }; |
| 1598 |
| 1599 RunParserSyncTest(context_data, statement_data, kError); |
| 1600 } |
| 1601 |
| 1602 |
| 1603 TEST(NoErrorsYieldClassic) { |
| 1604 // In classic mode, it's okay to use "yield" as identifier, *except* inside a |
| 1605 // generator (see next test). |
| 1606 const char* context_data[][2] = { |
| 1607 { "", "" }, |
| 1608 { "function is_not_gen() {", "}" }, |
| 1609 { NULL, NULL } |
| 1610 }; |
| 1611 |
| 1612 const char* statement_data[] = { |
| 1613 "var yield;", |
| 1614 "var foo, yield;", |
| 1615 "try { } catch (yield) { }", |
| 1616 "function yield() { }", |
| 1617 "function foo(yield) { }", |
| 1618 "function foo(bar, yield) { }", |
| 1619 "yield = 1;", |
| 1620 "var foo = yield = 1;", |
| 1621 "++yield;", |
| 1622 "yield++;", |
| 1623 NULL |
| 1624 }; |
| 1625 |
| 1626 RunParserSyncTest(context_data, statement_data, kSuccess); |
| 1627 } |
| 1628 |
| 1629 |
| 1630 TEST(ErrorsYieldClassicGenerator) { |
| 1631 const char* context_data[][2] = { |
| 1632 { "function * is_gen() {", "}" }, |
| 1633 { NULL, NULL } |
| 1634 }; |
| 1635 |
| 1636 const char* statement_data[] = { |
| 1637 "var yield;", |
| 1638 "var foo, yield;", |
| 1639 "try { } catch (yield) { }", |
| 1640 "function yield() { }", |
| 1641 // BUG: These should not be allowed, but they are (if kAllowGenerators is |
| 1642 // set) |
| 1643 // "function foo(yield) { }", |
| 1644 // "function foo(bar, yield) { }", |
| 1645 "yield = 1;", |
| 1646 "var foo = yield = 1;", |
| 1647 "++yield;", |
| 1648 "yield++;", |
| 1649 NULL |
| 1650 }; |
| 1651 |
| 1652 // If generators are not allowed, the error will be produced at the '*' token, |
| 1653 // so this test works both with and without the kAllowGenerators flag. |
| 1654 RunParserSyncTest(context_data, statement_data, kError); |
| 1655 } |
| 1656 |
| 1657 |
| 1658 TEST(ErrorsYieldStrict) { |
| 1659 const char* context_data[][2] = { |
| 1660 { "\"use strict\";", "" }, |
| 1661 { "\"use strict\"; function is_not_gen() {", "}" }, |
| 1662 { "function test_func() {\"use strict\"; ", "}"}, |
| 1663 { NULL, NULL } |
| 1664 }; |
| 1665 |
| 1666 const char* statement_data[] = { |
| 1667 "var yield;", |
| 1668 "var foo, yield;", |
| 1669 "try { } catch (yield) { }", |
| 1670 "function yield() { }", |
| 1671 "function foo(yield) { }", |
| 1672 "function foo(bar, yield) { }", |
| 1673 "yield = 1;", |
| 1674 "var foo = yield = 1;", |
| 1675 "++yield;", |
| 1676 "yield++;", |
| 1677 NULL |
| 1678 }; |
| 1679 |
| 1680 RunParserSyncTest(context_data, statement_data, kError); |
| 1681 } |
| 1682 |
| 1683 |
| 1684 TEST(ErrorsYield) { |
| 1685 const char* context_data[][2] = { |
| 1686 { "function * is_gen() {", "}" }, |
| 1687 { NULL, NULL } |
| 1688 }; |
| 1689 |
| 1690 const char* statement_data[] = { |
| 1691 "yield 2;", // this is legal inside generator |
| 1692 "yield * 2;", // this is legal inside generator |
| 1693 NULL |
| 1694 }; |
| 1695 |
| 1696 // Here we cannot assert that there is no error, since there will be without |
| 1697 // the kAllowGenerators flag. However, we test that Parser and PreParser |
| 1698 // produce the same errors. |
| 1699 RunParserSyncTest(context_data, statement_data, kSuccessOrError); |
| 1700 } |
| 1701 |
| 1702 |
| 1703 TEST(ErrorsNameOfStrictFunction) { |
| 1704 // Tests that illegal tokens as names of a strict function produce the correct |
| 1705 // errors. |
| 1706 const char* context_data[][2] = { |
| 1707 { "", ""}, |
| 1708 { "\"use strict\";", ""}, |
| 1709 { NULL, NULL } |
| 1710 }; |
| 1711 |
| 1712 const char* statement_data[] = { |
| 1713 "function eval() {\"use strict\";}", |
| 1714 "function arguments() {\"use strict\";}", |
| 1715 "function interface() {\"use strict\";}", |
| 1716 "function yield() {\"use strict\";}", |
| 1717 // Future reserved words are always illegal |
| 1718 "function super() { }", |
| 1719 "function super() {\"use strict\";}", |
| 1720 NULL |
| 1721 }; |
| 1722 |
| 1723 RunParserSyncTest(context_data, statement_data, kError); |
| 1724 } |
| 1725 |
| 1726 |
| 1727 TEST(NoErrorsNameOfStrictFunction) { |
| 1728 const char* context_data[][2] = { |
| 1729 { "", ""}, |
| 1730 { NULL, NULL } |
| 1731 }; |
| 1732 |
| 1733 const char* statement_data[] = { |
| 1734 "function eval() { }", |
| 1735 "function arguments() { }", |
| 1736 "function interface() { }", |
| 1737 "function yield() { }", |
| 1738 NULL |
| 1739 }; |
| 1740 |
| 1741 RunParserSyncTest(context_data, statement_data, kSuccess); |
| 1742 } |
| 1743 |
| 1744 |
| 1745 |
| 1746 TEST(ErrorsIllegalWordsAsLabelsClassic) { |
| 1747 // Using future reserved words as labels is always an error. |
| 1748 const char* context_data[][2] = { |
| 1749 { "", ""}, |
| 1750 { "function test_func() {", "}" }, |
| 1751 { NULL, NULL } |
| 1752 }; |
| 1753 |
| 1754 const char* statement_data[] = { |
| 1755 "super: while(true) { break super; }", |
| 1756 NULL |
| 1757 }; |
| 1758 |
| 1759 RunParserSyncTest(context_data, statement_data, kError); |
| 1760 } |
| 1761 |
| 1762 |
| 1763 TEST(ErrorsIllegalWordsAsLabelsStrict) { |
| 1764 // Tests that illegal tokens as labels produce the correct errors. |
| 1765 const char* context_data[][2] = { |
| 1766 { "\"use strict\";", "" }, |
| 1767 { "function test_func() {\"use strict\"; ", "}"}, |
| 1768 { NULL, NULL } |
| 1769 }; |
| 1770 |
| 1771 const char* statement_data[] = { |
| 1772 "super: while(true) { break super; }", |
| 1773 "interface: while(true) { break interface; }", |
| 1774 "yield: while(true) { break yield; }", |
| 1775 NULL |
| 1776 }; |
| 1777 |
| 1778 RunParserSyncTest(context_data, statement_data, kError); |
| 1779 } |
| 1780 |
| 1781 |
| 1782 TEST(NoErrorsIllegalWordsAsLabels) { |
| 1783 // Using eval and arguments as labels is legal even in strict mode. |
| 1784 const char* context_data[][2] = { |
| 1785 { "", ""}, |
| 1786 { "function test_func() {", "}" }, |
| 1787 { "\"use strict\";", "" }, |
| 1788 { "\"use strict\"; function test_func() {", "}" }, |
| 1789 { NULL, NULL } |
| 1790 }; |
| 1791 |
| 1792 const char* statement_data[] = { |
| 1793 "mylabel: while(true) { break mylabel; }", |
| 1794 "eval: while(true) { break eval; }", |
| 1795 "arguments: while(true) { break arguments; }", |
| 1796 NULL |
| 1797 }; |
| 1798 |
| 1799 RunParserSyncTest(context_data, statement_data, kSuccess); |
| 1800 } |
| 1801 |
| 1802 |
| 1803 TEST(ErrorsParenthesizedLabels) { |
| 1804 // Parenthesized identifiers shouldn't be recognized as labels. |
| 1805 const char* context_data[][2] = { |
| 1806 { "", ""}, |
| 1807 { "function test_func() {", "}" }, |
| 1808 { NULL, NULL } |
| 1809 }; |
| 1810 |
| 1811 const char* statement_data[] = { |
| 1812 "(mylabel): while(true) { break mylabel; }", |
| 1813 NULL |
| 1814 }; |
| 1815 |
| 1816 RunParserSyncTest(context_data, statement_data, kError); |
| 1817 } |
| 1818 |
| 1819 |
| 1820 TEST(NoErrorsParenthesizedDirectivePrologue) { |
| 1821 // Parenthesized directive prologue shouldn't be recognized. |
| 1822 const char* context_data[][2] = { |
| 1823 { "", ""}, |
| 1824 { NULL, NULL } |
| 1825 }; |
| 1826 |
| 1827 const char* statement_data[] = { |
| 1828 "(\"use strict\"); var eval;", |
| 1829 NULL |
| 1830 }; |
| 1831 |
| 1832 RunParserSyncTest(context_data, statement_data, kSuccess); |
| 1833 } |
| 1834 |
| 1835 |
| 1836 TEST(ErrorsNotAnIdentifierName) { |
| 1837 const char* context_data[][2] = { |
| 1838 { "", ""}, |
| 1839 { "\"use strict\";", ""}, |
| 1840 { NULL, NULL } |
| 1841 }; |
| 1842 |
| 1843 const char* statement_data[] = { |
| 1844 "var foo = {}; foo.{;", |
| 1845 "var foo = {}; foo.};", |
| 1846 "var foo = {}; foo.=;", |
| 1847 "var foo = {}; foo.888;", |
| 1848 "var foo = {}; foo.-;", |
| 1849 "var foo = {}; foo.--;", |
| 1850 NULL |
| 1851 }; |
| 1852 |
| 1853 RunParserSyncTest(context_data, statement_data, kError); |
| 1854 } |
| 1855 |
| 1856 |
| 1857 TEST(NoErrorsIdentifierNames) { |
| 1858 // Keywords etc. are valid as property names. |
| 1859 const char* context_data[][2] = { |
| 1860 { "", ""}, |
| 1861 { "\"use strict\";", ""}, |
| 1862 { NULL, NULL } |
| 1863 }; |
| 1864 |
| 1865 const char* statement_data[] = { |
| 1866 "var foo = {}; foo.if;", |
| 1867 "var foo = {}; foo.yield;", |
| 1868 "var foo = {}; foo.super;", |
| 1869 "var foo = {}; foo.interface;", |
| 1870 "var foo = {}; foo.eval;", |
| 1871 "var foo = {}; foo.arguments;", |
| 1872 NULL |
| 1873 }; |
| 1874 |
| 1875 RunParserSyncTest(context_data, statement_data, kSuccess); |
| 1876 } |
| 1877 |
| 1878 |
| 1879 TEST(DontRegressPreParserDataSizes) { |
| 1880 // These tests make sure that PreParser doesn't start producing less data. |
| 1881 |
| 1882 v8::V8::Initialize(); |
| 1883 |
| 1884 int marker; |
| 1885 CcTest::i_isolate()->stack_guard()->SetStackLimit( |
| 1886 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); |
| 1887 |
| 1888 struct TestCase { |
| 1889 const char* program; |
| 1890 int symbols; |
| 1891 int functions; |
| 1892 } test_cases[] = { |
| 1893 // Labels, variables and functions are recorded as symbols. |
| 1894 {"{label: 42}", 1, 0}, {"{label: 42; label2: 43}", 2, 0}, |
| 1895 {"var x = 42;", 1, 0}, {"var x = 42, y = 43;", 2, 0}, |
| 1896 {"function foo() {}", 1, 1}, {"function foo() {} function bar() {}", 2, 2}, |
| 1897 // Labels, variables and functions insize lazy functions are not recorded. |
| 1898 {"function lazy() { var a, b, c; }", 1, 1}, |
| 1899 {"function lazy() { a: 1; b: 2; c: 3; }", 1, 1}, |
| 1900 {"function lazy() { function a() {} function b() {} function c() {} }", 1, |
| 1901 1}, |
| 1902 {NULL, 0, 0} |
| 1903 }; |
| 1904 // Each function adds 5 elements to the preparse function data. |
| 1905 const int kDataPerFunction = 5; |
| 1906 |
| 1907 uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); |
| 1908 for (int i = 0; test_cases[i].program; i++) { |
| 1909 const char* program = test_cases[i].program; |
| 1910 i::Utf8ToUtf16CharacterStream stream( |
| 1911 reinterpret_cast<const i::byte*>(program), |
| 1912 static_cast<unsigned>(strlen(program))); |
| 1913 i::CompleteParserRecorder log; |
| 1914 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); |
| 1915 scanner.Initialize(&stream); |
| 1916 |
| 1917 i::PreParser preparser(&scanner, &log, stack_limit); |
| 1918 preparser.set_allow_lazy(true); |
| 1919 preparser.set_allow_natives_syntax(true); |
| 1920 i::PreParser::PreParseResult result = preparser.PreParseProgram(); |
| 1921 CHECK_EQ(i::PreParser::kPreParseSuccess, result); |
| 1922 if (log.symbol_ids() != test_cases[i].symbols) { |
| 1923 i::OS::Print( |
| 1924 "Expected preparse data for program:\n" |
| 1925 "\t%s\n" |
| 1926 "to contain %d symbols, however, received %d symbols.\n", |
| 1927 program, test_cases[i].symbols, log.symbol_ids()); |
| 1928 CHECK(false); |
| 1929 } |
| 1930 if (log.function_position() != test_cases[i].functions * kDataPerFunction) { |
| 1931 i::OS::Print( |
| 1932 "Expected preparse data for program:\n" |
| 1933 "\t%s\n" |
| 1934 "to contain %d functions, however, received %d functions.\n", |
| 1935 program, test_cases[i].functions, |
| 1936 log.function_position() / kDataPerFunction); |
| 1937 CHECK(false); |
| 1938 } |
| 1939 i::ScriptDataImpl data(log.ExtractData()); |
| 1940 CHECK(!data.has_error()); |
| 1941 } |
| 1942 } |
| 1943 |
| 1944 |
| 1945 TEST(FunctionDeclaresItselfStrict) { |
| 1946 // Tests that we produce the right kinds of errors when a function declares |
| 1947 // itself strict (we cannot produce there errors as soon as we see the |
| 1948 // offending identifiers, because we don't know at that point whether the |
| 1949 // function is strict or not). |
| 1950 const char* context_data[][2] = { |
| 1951 {"function eval() {", "}"}, |
| 1952 {"function arguments() {", "}"}, |
| 1953 {"function yield() {", "}"}, |
| 1954 {"function interface() {", "}"}, |
| 1955 {"function foo(eval) {", "}"}, |
| 1956 {"function foo(arguments) {", "}"}, |
| 1957 {"function foo(yield) {", "}"}, |
| 1958 {"function foo(interface) {", "}"}, |
| 1959 {"function foo(bar, eval) {", "}"}, |
| 1960 {"function foo(bar, arguments) {", "}"}, |
| 1961 {"function foo(bar, yield) {", "}"}, |
| 1962 {"function foo(bar, interface) {", "}"}, |
| 1963 {"function foo(bar, bar) {", "}"}, |
| 1964 { NULL, NULL } |
| 1965 }; |
| 1966 |
| 1967 const char* strict_statement_data[] = { |
| 1968 "\"use strict\";", |
| 1969 NULL |
| 1970 }; |
| 1971 |
| 1972 const char* non_strict_statement_data[] = { |
| 1973 ";", |
| 1974 NULL |
| 1975 }; |
| 1976 |
| 1977 RunParserSyncTest(context_data, strict_statement_data, kError); |
| 1978 RunParserSyncTest(context_data, non_strict_statement_data, kSuccess); |
| 1979 } |
| 1980 |
| 1981 |
| 1982 TEST(ErrorsTryWithoutCatchOrFinally) { |
| 1983 const char* context_data[][2] = { |
| 1984 {"", ""}, |
| 1985 { NULL, NULL } |
| 1986 }; |
| 1987 |
| 1988 const char* statement_data[] = { |
| 1989 "try { }", |
| 1990 "try { } foo();", |
| 1991 "try { } catch (e) foo();", |
| 1992 "try { } catch { }", |
| 1993 "try { } finally foo();", |
| 1994 NULL |
| 1995 }; |
| 1996 |
| 1997 RunParserSyncTest(context_data, statement_data, kError); |
| 1998 } |
| 1999 |
| 2000 |
| 2001 TEST(NoErrorsTryCatchFinally) { |
| 2002 const char* context_data[][2] = { |
| 2003 {"", ""}, |
| 2004 { NULL, NULL } |
| 2005 }; |
| 2006 |
| 2007 const char* statement_data[] = { |
| 2008 "try { } catch (e) { }", |
| 2009 "try { } catch (e) { } finally { }", |
| 2010 "try { } finally { }", |
| 2011 NULL |
| 2012 }; |
| 2013 |
| 2014 RunParserSyncTest(context_data, statement_data, kSuccess); |
| 2015 } |
| OLD | NEW |