Index: test/cctest/test-parsing.cc |
diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc |
index ec1c9dd5aa2e930810e4629db78a7389ee9a0bd2..41d8dfe42a6f8bed6266308ea00d42e8ad0abe78 100644 |
--- a/test/cctest/test-parsing.cc |
+++ b/test/cctest/test-parsing.cc |
@@ -1360,7 +1360,8 @@ enum ParserFlag { |
kAllowHarmonyTemplates, |
kAllowHarmonySloppy, |
kAllowHarmonyUnicode, |
- kAllowHarmonyComputedPropertyNames |
+ kAllowHarmonyComputedPropertyNames, |
+ kAllowStrongMode |
}; |
@@ -1391,6 +1392,7 @@ void SetParserFlags(i::ParserBase<Traits>* parser, |
parser->set_allow_harmony_unicode(flags.Contains(kAllowHarmonyUnicode)); |
parser->set_allow_harmony_computed_property_names( |
flags.Contains(kAllowHarmonyComputedPropertyNames)); |
+ parser->set_allow_strong_mode(flags.Contains(kAllowStrongMode)); |
} |
@@ -1760,10 +1762,11 @@ TEST(ErrorsEvalAndArguments) { |
// ok to use "eval" or "arguments" as identifiers. With the strict mode, it |
// isn't. |
const char* context_data[][2] = { |
- { "\"use strict\";", "" }, |
- { "var eval; function test_func() {\"use strict\"; ", "}"}, |
- { NULL, NULL } |
- }; |
+ {"\"use strict\";", ""}, |
+ {"\"use strong\";", ""}, |
+ {"var eval; function test_func() {\"use strict\"; ", "}"}, |
+ {"var eval; function test_func() {\"use strong\"; ", "}"}, |
+ {NULL, NULL}}; |
const char* statement_data[] = { |
"var eval;", |
@@ -1793,7 +1796,9 @@ TEST(ErrorsEvalAndArguments) { |
NULL |
}; |
- RunParserSyncTest(context_data, statement_data, kError); |
+ static const ParserFlag always_flags[] = {kAllowStrongMode}; |
+ RunParserSyncTest(context_data, statement_data, kError, NULL, 0, always_flags, |
+ arraysize(always_flags)); |
} |
@@ -1900,18 +1905,22 @@ TEST(ErrorsFutureStrictReservedWords) { |
// it's ok to use future strict reserved words as identifiers. With the strict |
// mode, it isn't. |
const char* context_data[][2] = { |
- { "function test_func() {\"use strict\"; ", "}"}, |
- { "() => { \"use strict\"; ", "}" }, |
- { NULL, NULL } |
- }; |
+ {"function test_func() {\"use strict\"; ", "}"}, |
+ {"() => { \"use strict\"; ", "}"}, |
+ {"function test_func() {\"use strong\"; ", "}"}, |
+ {"() => { \"use strong\"; ", "}"}, |
+ {NULL, NULL}}; |
const char* statement_data[] { |
LIMITED_FUTURE_STRICT_RESERVED_WORDS(FUTURE_STRICT_RESERVED_STATEMENTS) |
NULL |
}; |
- RunParserSyncTest(context_data, statement_data, kError); |
- RunParserSyncTest(context_data, statement_data, kError); |
+ static const ParserFlag always_flags[] = {kAllowStrongMode}; |
+ RunParserSyncTest(context_data, statement_data, kError, NULL, 0, always_flags, |
+ arraysize(always_flags)); |
+ RunParserSyncTest(context_data, statement_data, kError, NULL, 0, always_flags, |
+ arraysize(always_flags)); |
} |
@@ -2089,15 +2098,21 @@ TEST(NoErrorsYieldSloppyGeneratorsEnabled) { |
TEST(ErrorsYieldStrict) { |
const char* context_data[][2] = { |
- { "\"use strict\";", "" }, |
- { "\"use strict\"; function not_gen() {", "}" }, |
- { "function test_func() {\"use strict\"; ", "}"}, |
- { "\"use strict\"; function * gen() { function not_gen() {", "} }" }, |
- { "\"use strict\"; (function not_gen() {", "})" }, |
- { "\"use strict\"; (function * gen() { (function not_gen() {", "}) })" }, |
- { "() => {\"use strict\"; ", "}" }, |
- { NULL, NULL } |
- }; |
+ {"\"use strict\";", ""}, |
+ {"\"use strict\"; function not_gen() {", "}"}, |
+ {"function test_func() {\"use strict\"; ", "}"}, |
+ {"\"use strict\"; function * gen() { function not_gen() {", "} }"}, |
+ {"\"use strict\"; (function not_gen() {", "})"}, |
+ {"\"use strict\"; (function * gen() { (function not_gen() {", "}) })"}, |
+ {"() => {\"use strict\"; ", "}"}, |
+ {"\"use strong\";", ""}, |
+ {"\"use strong\"; function not_gen() {", "}"}, |
+ {"function test_func() {\"use strong\"; ", "}"}, |
+ {"\"use strong\"; function * gen() { function not_gen() {", "} }"}, |
+ {"\"use strong\"; (function not_gen() {", "})"}, |
+ {"\"use strong\"; (function * gen() { (function not_gen() {", "}) })"}, |
+ {"() => {\"use strong\"; ", "}"}, |
+ {NULL, NULL}}; |
const char* statement_data[] = { |
"var yield;", |
@@ -2117,7 +2132,9 @@ TEST(ErrorsYieldStrict) { |
NULL |
}; |
- RunParserSyncTest(context_data, statement_data, kError); |
+ static const ParserFlag always_flags[] = {kAllowStrongMode}; |
+ RunParserSyncTest(context_data, statement_data, kError, NULL, 0, always_flags, |
+ arraysize(always_flags)); |
} |
@@ -2235,8 +2252,10 @@ TEST(ErrorsNameOfStrictFunction) { |
const char* context_data[][2] = { |
{ "function ", ""}, |
{ "\"use strict\"; function", ""}, |
+ { "\"use strong\"; function", ""}, |
{ "function * ", ""}, |
{ "\"use strict\"; function * ", ""}, |
+ { "\"use strong\"; function * ", ""}, |
{ NULL, NULL } |
}; |
@@ -2251,7 +2270,9 @@ TEST(ErrorsNameOfStrictFunction) { |
NULL |
}; |
- RunParserSyncTest(context_data, statement_data, kError); |
+ static const ParserFlag always_flags[] = {kAllowStrongMode}; |
+ RunParserSyncTest(context_data, statement_data, kError, NULL, 0, always_flags, |
+ arraysize(always_flags)); |
} |
@@ -2312,11 +2333,13 @@ TEST(ErrorsIllegalWordsAsLabelsSloppy) { |
TEST(ErrorsIllegalWordsAsLabelsStrict) { |
// Tests that illegal tokens as labels produce the correct errors. |
const char* context_data[][2] = { |
- { "\"use strict\";", "" }, |
- { "function test_func() {\"use strict\"; ", "}"}, |
- { "() => {\"use strict\"; ", "}" }, |
- { NULL, NULL } |
- }; |
+ {"\"use strict\";", ""}, |
+ {"function test_func() {\"use strict\"; ", "}"}, |
+ {"() => {\"use strict\"; ", "}"}, |
+ {"\"use strong\";", ""}, |
+ {"function test_func() {\"use strong\"; ", "}"}, |
+ {"() => {\"use strong\"; ", "}"}, |
+ {NULL, NULL}}; |
#define LABELLED_WHILE(NAME) #NAME ": while (true) { break " #NAME "; }", |
const char* statement_data[] = { |
@@ -2326,7 +2349,9 @@ TEST(ErrorsIllegalWordsAsLabelsStrict) { |
}; |
#undef LABELLED_WHILE |
- RunParserSyncTest(context_data, statement_data, kError); |
+ static const ParserFlag always_flags[] = {kAllowStrongMode}; |
+ RunParserSyncTest(context_data, statement_data, kError, NULL, 0, always_flags, |
+ arraysize(always_flags)); |
} |
@@ -2403,10 +2428,13 @@ TEST(NoErrorsParenthesizedDirectivePrologue) { |
const char* statement_data[] = { |
"(\"use strict\"); var eval;", |
+ "(\"use strong\"); var eval;", |
NULL |
}; |
- RunParserSyncTest(context_data, statement_data, kSuccess); |
+ static const ParserFlag always_flags[] = {kAllowStrongMode}; |
+ RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0, |
+ always_flags, arraysize(always_flags)); |
} |
@@ -2530,6 +2558,7 @@ TEST(FunctionDeclaresItselfStrict) { |
const char* strict_statement_data[] = { |
"\"use strict\";", |
+ "\"use strong\";", |
NULL |
}; |
@@ -2538,8 +2567,11 @@ TEST(FunctionDeclaresItselfStrict) { |
NULL |
}; |
- RunParserSyncTest(context_data, strict_statement_data, kError); |
- RunParserSyncTest(context_data, non_strict_statement_data, kSuccess); |
+ static const ParserFlag always_flags[] = {kAllowStrongMode}; |
+ RunParserSyncTest(context_data, strict_statement_data, kError, NULL, 0, |
+ always_flags, arraysize(always_flags)); |
+ RunParserSyncTest(context_data, non_strict_statement_data, kSuccess, NULL, 0, |
+ always_flags, arraysize(always_flags)); |
} |
@@ -2831,6 +2863,7 @@ TEST(StrictDelete) { |
// "delete <Identifier>" is not allowed in strict mode. |
const char* strict_context_data[][2] = { |
{"\"use strict\"; ", ""}, |
+ {"\"use strong\"; ", ""}, |
{ NULL, NULL } |
}; |
@@ -2870,14 +2903,21 @@ TEST(StrictDelete) { |
NULL |
}; |
- RunParserSyncTest(strict_context_data, sloppy_statement_data, kError); |
- RunParserSyncTest(sloppy_context_data, sloppy_statement_data, kSuccess); |
+ static const ParserFlag always_flags[] = {kAllowStrongMode}; |
+ RunParserSyncTest(strict_context_data, sloppy_statement_data, kError, NULL, 0, |
+ always_flags, arraysize(always_flags)); |
+ RunParserSyncTest(sloppy_context_data, sloppy_statement_data, kSuccess, NULL, |
+ 0, always_flags, arraysize(always_flags)); |
- RunParserSyncTest(strict_context_data, good_statement_data, kSuccess); |
- RunParserSyncTest(sloppy_context_data, good_statement_data, kSuccess); |
+ RunParserSyncTest(strict_context_data, good_statement_data, kSuccess, NULL, 0, |
+ always_flags, arraysize(always_flags)); |
+ RunParserSyncTest(sloppy_context_data, good_statement_data, kSuccess, NULL, 0, |
+ always_flags, arraysize(always_flags)); |
- RunParserSyncTest(strict_context_data, bad_statement_data, kError); |
- RunParserSyncTest(sloppy_context_data, bad_statement_data, kError); |
+ RunParserSyncTest(strict_context_data, bad_statement_data, kError, NULL, 0, |
+ always_flags, arraysize(always_flags)); |
+ RunParserSyncTest(sloppy_context_data, bad_statement_data, kError, NULL, 0, |
+ always_flags, arraysize(always_flags)); |
} |
@@ -4970,6 +5010,12 @@ TEST(DeclarationsError) { |
{"'use strict'; for (;;)", ""}, |
{"'use strict'; for (x in y)", ""}, |
{"'use strict'; do ", " while (false)"}, |
+ {"'use strong'; if (true)", ""}, |
+ {"'use strong'; if (false) {} else", ""}, |
+ {"'use strong'; while (false)", ""}, |
+ {"'use strong'; for (;;)", ""}, |
+ {"'use strong'; for (x in y)", ""}, |
+ {"'use strong'; do ", " while (false)"}, |
{NULL, NULL}}; |
const char* statement_data[] = { |
@@ -4979,8 +5025,50 @@ TEST(DeclarationsError) { |
NULL}; |
static const ParserFlag always_flags[] = { |
- kAllowHarmonyClasses, kAllowHarmonyScoping |
- }; |
+ kAllowHarmonyClasses, kAllowHarmonyScoping, kAllowStrongMode}; |
RunParserSyncTest(context_data, statement_data, kError, NULL, 0, |
always_flags, arraysize(always_flags)); |
} |
+ |
+ |
+void TestLanguageMode(const char* source, |
+ i::LanguageMode expected_language_mode) { |
+ i::Isolate* isolate = CcTest::i_isolate(); |
+ i::Factory* factory = isolate->factory(); |
+ v8::HandleScope handles(CcTest::isolate()); |
+ v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate()); |
+ v8::Context::Scope context_scope(context); |
+ isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() - |
+ 128 * 1024); |
+ |
+ i::Handle<i::Script> script = |
+ factory->NewScript(factory->NewStringFromAsciiChecked(source)); |
+ i::CompilationInfoWithZone info(script); |
+ i::Parser::ParseInfo parse_info = {isolate->stack_guard()->real_climit(), |
+ isolate->heap()->HashSeed(), |
+ isolate->unicode_cache()}; |
+ i::Parser parser(&info, &parse_info); |
+ parser.set_allow_strong_mode(true); |
+ info.MarkAsGlobal(); |
+ parser.Parse(); |
+ CHECK(info.function() != NULL); |
+ CHECK_EQ(expected_language_mode, info.function()->language_mode()); |
+} |
+ |
+ |
+TEST(LanguageModeDirectives) { |
+ TestLanguageMode("\"use nothing\"", i::SLOPPY); |
+ TestLanguageMode("\"use strict\"", i::STRICT); |
+ TestLanguageMode("\"use strong\"", i::STRONG); |
+ |
+ TestLanguageMode("var x = 1; \"use strict\"", i::SLOPPY); |
+ TestLanguageMode("var x = 1; \"use strong\"", i::SLOPPY); |
+ |
+ // Test that multiple directives ("use strict" / "use strong") put the parser |
+ // into the correct mode. |
+ TestLanguageMode("\"use strict\"; \"use strong\";", i::STRONG); |
+ TestLanguageMode("\"use strong\"; \"use strict\";", i::STRONG); |
+ |
+ TestLanguageMode("\"use some future directive\"; \"use strict\";", i::STRICT); |
+ TestLanguageMode("\"use some future directive\"; \"use strong\";", i::STRONG); |
+} |