| Index: src/preparser.h
 | 
| diff --git a/src/preparser.h b/src/preparser.h
 | 
| index 3a68bed6c9f8e23769fe258735d7831a98fc40f3..d0c7e3e198f8eb4e2f417f0b1f5b74ace00ad45a 100644
 | 
| --- a/src/preparser.h
 | 
| +++ b/src/preparser.h
 | 
| @@ -347,6 +347,8 @@ class PreParser : public ParserBase {
 | 
|    // 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() {
 | 
| @@ -387,8 +389,21 @@ class PreParser : public ParserBase {
 | 
|            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;
 | 
|      }
 | 
| @@ -405,10 +420,27 @@ class PreParser : public ParserBase {
 | 
|        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
 | 
| @@ -420,6 +452,9 @@ class PreParser : public ParserBase {
 | 
|        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,
 | 
| @@ -445,11 +480,13 @@ class PreParser : public ParserBase {
 | 
|      // Preserves being an unparenthesized string literal, possibly
 | 
|      // "use strict".
 | 
|      static Statement ExpressionStatement(Expression expression) {
 | 
| -      if (expression.IsUseStrictLiteral()) {
 | 
| -        return Statement(kUseStrictExpressionStatement);
 | 
| -      }
 | 
| -      if (expression.IsStringLiteral()) {
 | 
| -        return Statement(kStringLiteralExpressionStatement);
 | 
| +      if (!expression.IsParenthesized()) {
 | 
| +        if (expression.IsUseStrictLiteral()) {
 | 
| +          return Statement(kUseStrictExpressionStatement);
 | 
| +        }
 | 
| +        if (expression.IsStringLiteral()) {
 | 
| +          return Statement(kStringLiteralExpressionStatement);
 | 
| +        }
 | 
|        }
 | 
|        return Default();
 | 
|      }
 | 
| 
 |