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.

Reply via email to