Revision: 19153
Author: [email protected]
Date: Thu Feb 6 13:12:10 2014 UTC
Log: Redo r19140 with better efficiency.
Still relevant parts of the original commit message:
Unify paren handling in Parser and PreParser.
It is only needed in (Pre)Parser::ParseExpressionOrLabelledStatement for not
recognizing parenthesized identifiers as labels and in
(Pre)Parser::ParseSourceElements for not recognizing a parenthesized string
as
directive prologue.
Parser Expressions don't keep track of whether they're parenthesized, so
PreParser Expressions shouldn't either.
BUG=3126
LOG=N
[email protected]
Review URL: https://codereview.chromium.org/148323011
http://code.google.com/p/v8/source/detail?r=19153
Modified:
/branches/bleeding_edge/src/preparser.cc
/branches/bleeding_edge/src/preparser.h
/branches/bleeding_edge/test/cctest/test-parsing.cc
=======================================
--- /branches/bleeding_edge/src/preparser.cc Thu Feb 6 11:59:16 2014 UTC
+++ /branches/bleeding_edge/src/preparser.cc Thu Feb 6 13:12:10 2014 UTC
@@ -168,15 +168,18 @@
// SourceElements ::
// (Statement)* <end_token>
- bool allow_directive_prologue = true;
+ bool directive_prologue = true;
while (peek() != end_token) {
+ if (directive_prologue && peek() != Token::STRING) {
+ directive_prologue = false;
+ }
Statement statement = ParseSourceElement(CHECK_OK);
- if (allow_directive_prologue) {
+ if (directive_prologue) {
if (statement.IsUseStrictLiteral()) {
set_language_mode(allow_harmony_scoping() ?
EXTENDED_MODE : STRICT_MODE);
} else if (!statement.IsStringLiteral()) {
- allow_directive_prologue = false;
+ directive_prologue = false;
}
}
}
@@ -468,16 +471,20 @@
// Expression ';'
// Identifier ':' Statement
+ bool starts_with_identifier = peek_any_identifier();
Expression expr = ParseExpression(true, CHECK_OK);
- if (expr.IsRawIdentifier()) {
+ // Even if the expression starts with an identifier, it is not
necessarily an
+ // identifier. For example, "foo + bar" starts with an identifier but is
not
+ // an identifier.
+ if (starts_with_identifier && expr.IsIdentifier() && peek() ==
Token::COLON) {
+ // Expression is a single identifier, and not, e.g., a parenthesized
+ // identifier.
ASSERT(!expr.AsIdentifier().IsFutureReserved());
ASSERT(is_classic_mode() ||
(!expr.AsIdentifier().IsFutureStrictReserved() &&
!expr.AsIdentifier().IsYield()));
- if (peek() == Token::COLON) {
- Consume(Token::COLON);
- return ParseStatement(ok);
- }
+ Consume(Token::COLON);
+ return ParseStatement(ok);
// Preparsing is disabled for extensions (because the extension details
// aren't passed to lazily compiled functions), so we don't
// accept "native function" in the preparser.
@@ -1170,7 +1177,6 @@
parenthesized_function_ = (peek() == Token::FUNCTION);
result = ParseExpression(true, CHECK_OK);
Expect(Token::RPAREN, CHECK_OK);
- result = result.Parenthesize();
break;
case Token::MOD:
=======================================
--- /branches/bleeding_edge/src/preparser.h Thu Feb 6 11:59:16 2014 UTC
+++ /branches/bleeding_edge/src/preparser.h Thu Feb 6 13:12:10 2014 UTC
@@ -347,8 +347,6 @@
// if bit 1 is set, it's a string literal.
// If neither is set, it's no particular type, and both set isn't
// use yet.
- // Bit 2 is used to mark the expression as being parenthesized,
- // so "(foo)" isn't recognized as a pure identifier (and possible label).
class Expression {
public:
static Expression Default() {
@@ -388,21 +386,8 @@
return PreParser::Identifier(
static_cast<PreParser::Identifier::Type>(code_ >>
kIdentifierShift));
}
-
- bool IsParenthesized() {
- // If bit 0 or 1 is set, we interpret bit 2 as meaning parenthesized.
- return (code_ & 7) > 4;
- }
-
- bool IsRawIdentifier() {
- return !IsParenthesized() && IsIdentifier();
- }
bool IsStringLiteral() { return (code_ & kStringLiteralFlag) != 0; }
-
- bool IsRawStringLiteral() {
- return !IsParenthesized() && IsStringLiteral();
- }
bool IsUseStrictLiteral() {
return (code_ & kStringLiteralMask) == kUseStrictString;
@@ -419,28 +404,11 @@
bool IsStrictFunction() {
return code_ == kStrictFunctionExpression;
}
-
- Expression Parenthesize() {
- int type = code_ & 3;
- if (type != 0) {
- // Identifiers and string literals can be parenthesized.
- // They no longer work as labels or directive prologues,
- // but are still recognized in other contexts.
- return Expression(code_ | kParenthesizedExpressionFlag);
- }
- // For other types of expressions, it's not important to remember
- // the parentheses.
- return *this;
- }
private:
// First two/three bits are used as flags.
// Bit 0 and 1 represent identifiers or strings literals, and are
// mutually exclusive, but can both be absent.
- // If bit 0 or 1 are set, bit 2 marks that the expression has
- // been wrapped in parentheses (a string literal can no longer
- // be a directive prologue, and an identifier can no longer be
- // a label.
enum {
kUnknownExpression = 0,
// Identifiers
@@ -452,9 +420,6 @@
kUseStrictString = kStringLiteralFlag | 8,
kStringLiteralMask = kUseStrictString,
- // Only if identifier or string literal.
- kParenthesizedExpressionFlag = 4,
-
// Below here applies if neither identifier nor string literal.
kThisExpression = 4,
kThisPropertyExpression = 8,
@@ -480,13 +445,11 @@
// Preserves being an unparenthesized string literal, possibly
// "use strict".
static Statement ExpressionStatement(Expression expression) {
- if (!expression.IsParenthesized()) {
- if (expression.IsUseStrictLiteral()) {
- return Statement(kUseStrictExpressionStatement);
- }
- if (expression.IsStringLiteral()) {
- return Statement(kStringLiteralExpressionStatement);
- }
+ if (expression.IsUseStrictLiteral()) {
+ return Statement(kUseStrictExpressionStatement);
+ }
+ if (expression.IsStringLiteral()) {
+ return Statement(kStringLiteralExpressionStatement);
}
return Default();
}
=======================================
--- /branches/bleeding_edge/test/cctest/test-parsing.cc Thu Feb 6 11:59:16
2014 UTC
+++ /branches/bleeding_edge/test/cctest/test-parsing.cc Thu Feb 6 13:12:10
2014 UTC
@@ -1798,3 +1798,36 @@
RunParserSyncTest(context_data, statement_data, kSuccess);
}
+
+
+TEST(ErrorsParenthesizedLabels) {
+ // Parenthesized identifiers shouldn't be recognized as labels.
+ const char* context_data[][2] = {
+ { "", ""},
+ { "function test_func() {", "}" },
+ { NULL, NULL }
+ };
+
+ const char* statement_data[] = {
+ "(mylabel): while(true) { break mylabel; }",
+ NULL
+ };
+
+ RunParserSyncTest(context_data, statement_data, kError);
+}
+
+
+TEST(NoErrorsParenthesizedDirectivePrologue) {
+ // Parenthesized directive prologue shouldn't be recognized.
+ const char* context_data[][2] = {
+ { "", ""},
+ { NULL, NULL }
+ };
+
+ const char* statement_data[] = {
+ "(\"use strict\"); var eval;",
+ NULL
+ };
+
+ RunParserSyncTest(context_data, statement_data, kSuccess);
+}
--
--
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.