Revision: 19082
Author: [email protected]
Date: Tue Feb 4 18:16:45 2014 UTC
Log: Tests for (pre)parse errors when "yield" is found in
inappropriate places.
In addition:
- Fix: PreParser used to report an unexpected token one token too late when
ParsePrimaryExpression failed.
- Unified identifier handling (PreParser::GetIdentifier is now like
Parser::GetIdentifier).
- Fix: PreParser used to produce "unexpected_token YIELD" errors when Parser
produced "unexpected_token_identifier"; fixed PreParser to match Parser.
BUG=3126
LOG=N
[email protected]
Review URL: https://codereview.chromium.org/151103006
http://code.google.com/p/v8/source/detail?r=19082
Modified:
/branches/bleeding_edge/src/preparser.cc
/branches/bleeding_edge/test/cctest/test-parsing.cc
=======================================
--- /branches/bleeding_edge/src/preparser.cc Tue Feb 4 16:38:47 2014 UTC
+++ /branches/bleeding_edge/src/preparser.cc Tue Feb 4 18:16:45 2014 UTC
@@ -119,6 +119,7 @@
"unexpected_token_identifier", NULL);
case Token::FUTURE_RESERVED_WORD:
return ReportMessageAt(source_location, "unexpected_reserved", NULL);
+ case Token::YIELD:
case Token::FUTURE_STRICT_RESERVED_WORD:
return ReportMessageAt(source_location,
is_classic_mode() ? "unexpected_token_identifier"
@@ -1183,7 +1184,8 @@
break;
default: {
- Next();
+ Token::Value next = Next();
+ ReportUnexpectedToken(next);
*ok = false;
return Expression::Default();
}
@@ -1493,35 +1495,15 @@
PreParser::Identifier PreParser::ParseIdentifier(bool* ok) {
Token::Value next = Next();
- switch (next) {
- case Token::FUTURE_RESERVED_WORD: {
- Scanner::Location location = scanner()->location();
- ReportMessageAt(location.beg_pos, location.end_pos,
- "unexpected_reserved", NULL);
- *ok = false;
- return GetIdentifierSymbol();
- }
- case Token::YIELD:
- if (scope_->is_generator()) {
- // 'yield' in a generator is only valid as part of a
YieldExpression.
-
ReportMessageAt(scanner()->location(), "unexpected_token", "yield");
- *ok = false;
- return Identifier::Yield();
- }
- // FALLTHROUGH
- case Token::FUTURE_STRICT_RESERVED_WORD:
- if (!is_classic_mode()) {
- Scanner::Location location = scanner()->location();
- ReportMessageAt(location.beg_pos, location.end_pos,
- "unexpected_strict_reserved", NULL);
- *ok = false;
- }
- // FALLTHROUGH
- case Token::IDENTIFIER:
- return GetIdentifierSymbol();
- default:
- *ok = false;
- return Identifier::Default();
+ if (next == Token::IDENTIFIER ||
+ (is_classic_mode() &&
+ (next == Token::FUTURE_STRICT_RESERVED_WORD ||
+ (next == Token::YIELD && !scope_->is_generator())))) {
+ return GetIdentifierSymbol();
+ } else {
+ ReportUnexpectedToken(next);
+ *ok = false;
+ return Identifier::Default();
}
}
=======================================
--- /branches/bleeding_edge/test/cctest/test-parsing.cc Tue Feb 4 16:38:47
2014 UTC
+++ /branches/bleeding_edge/test/cctest/test-parsing.cc Tue Feb 4 18:16:45
2014 UTC
@@ -1531,3 +1531,68 @@
}
}
}
+
+
+TEST(ErrorsYield) {
+ // Tests that both preparsing and parsing produce the right kind of
errors for
+ // using yield as identifier. In non-strict mode, it's okay to
use "yield" as
+ // an identifier, *except* inside a generator function. In strict mode,
it's
+ // never okay.
+ const char* context_data[][2] = {
+ { "", "" },
+ { "\"use strict\";", "}" },
+ { "var eval; function test_func() {", "}"},
+ { "var eval; function test_func() {\"use strict\"; ", "}"},
+ { "function is_not_gen() {", "}" },
+ { "function * is_gen() {", "}" },
+ { "\"use strict\"; function is_not_gen() {", "}" },
+ { "\"use strict\"; function * is_gen() {", "}" },
+ { NULL, NULL }
+ };
+
+ const char* statement_data[] = {
+ "var yield;",
+ "var foo, yield;",
+ "try { } catch (yield) { }",
+ "function yield() { }",
+ "function foo(yield) { }",
+ "function foo(bar, yield) { }",
+ "yield = 1;",
+ "++yield;",
+ "yield++;",
+ "yield 2;", // this is legal inside generator
+ "yield * 2;", // this is legal inside generator
+ NULL
+ };
+
+ v8::HandleScope handles(CcTest::isolate());
+ v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate());
+ v8::Context::Scope context_scope(context);
+
+ int marker;
+ CcTest::i_isolate()->stack_guard()->SetStackLimit(
+ reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
+
+ static const ParserFlag flags[] = {
+ kAllowLazy, kAllowHarmonyScoping, kAllowModules, kAllowGenerators,
+ kAllowForOf
+ };
+ for (int i = 0; context_data[i][0] != NULL; ++i) {
+ for (int j = 0; statement_data[j] != NULL; ++j) {
+ int kPrefixLen = i::StrLength(context_data[i][0]);
+ int kStatementLen = i::StrLength(statement_data[j]);
+ int kSuffixLen = i::StrLength(context_data[i][1]);
+ int kProgramSize = kPrefixLen + kStatementLen + kSuffixLen;
+
+ // Plug the source code pieces together.
+ i::ScopedVector<char> program(kProgramSize + 1);
+ int length = i::OS::SNPrintF(program,
+ "%s%s%s",
+ context_data[i][0],
+ statement_data[j],
+ context_data[i][1]);
+ CHECK(length == kProgramSize);
+ TestParserSync(program.start(), flags, ARRAY_SIZE(flags));
+ }
+ }
+}
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.