Move ParseLeftHandSideExpression to ParserBase.
authormarja@chromium.org <marja@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 21 Mar 2014 09:51:33 +0000 (09:51 +0000)
committermarja@chromium.org <marja@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 21 Mar 2014 09:51:33 +0000 (09:51 +0000)
Includes cleanups:
- Reorganized functions in PreParserFactory to be in the logical order.
- De-hackified things PreParser doesn't need to track, such as IsCall & IsCallNew.

R=mstarzinger@chromium.org
BUG=

Review URL: https://codereview.chromium.org/206433003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20150 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/parser.cc
src/parser.h
src/preparser.cc
src/preparser.h

index 49fd7ba..c0d3360 100644 (file)
@@ -449,6 +449,16 @@ void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left,
 }
 
 
+void ParserTraits::CheckPossibleEvalCall(Expression* expression,
+                                         Scope* scope) {
+  VariableProxy* callee = expression->AsVariableProxy();
+  if (callee != NULL &&
+      callee->IsVariable(parser_->isolate()->factory()->eval_string())) {
+    scope->DeclarationScope()->RecordEvalCall();
+  }
+}
+
+
 Expression* ParserTraits::MarkExpressionAsLValue(Expression* expression) {
   VariableProxy* proxy = expression != NULL
       ? expression->AsVariableProxy()
@@ -740,8 +750,8 @@ FunctionLiteral* ParserTraits::ParseFunctionLiteral(
 }
 
 
-Expression* ParserTraits::ParseLeftHandSideExpression(bool* ok) {
-  return parser_->ParseLeftHandSideExpression(ok);
+Expression* ParserTraits::ParseMemberWithNewPrefixesExpression(bool* ok) {
+  return parser_->ParseMemberWithNewPrefixesExpression(ok);
 }
 
 
@@ -3043,79 +3053,6 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
 }
 
 
-Expression* Parser::ParseLeftHandSideExpression(bool* ok) {
-  // LeftHandSideExpression ::
-  //   (NewExpression | MemberExpression) ...
-
-  Expression* result = ParseMemberWithNewPrefixesExpression(CHECK_OK);
-
-  while (true) {
-    switch (peek()) {
-      case Token::LBRACK: {
-        Consume(Token::LBRACK);
-        int pos = position();
-        Expression* index = ParseExpression(true, CHECK_OK);
-        result = factory()->NewProperty(result, index, pos);
-        Expect(Token::RBRACK, CHECK_OK);
-        break;
-      }
-
-      case Token::LPAREN: {
-        int pos;
-        if (scanner()->current_token() == Token::IDENTIFIER) {
-          // For call of an identifier we want to report position of
-          // the identifier as position of the call in the stack trace.
-          pos = position();
-        } else {
-          // For other kinds of calls we record position of the parenthesis as
-          // position of the call.  Note that this is extremely important for
-          // expressions of the form function(){...}() for which call position
-          // should not point to the closing brace otherwise it will intersect
-          // with positions recorded for function literal and confuse debugger.
-          pos = peek_position();
-          // Also the trailing parenthesis are a hint that the function will
-          // be called immediately. If we happen to have parsed a preceding
-          // function literal eagerly, we can also compile it eagerly.
-          if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
-            result->AsFunctionLiteral()->set_parenthesized();
-          }
-        }
-        ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
-
-        // Keep track of eval() calls since they disable all local variable
-        // optimizations.
-        // The calls that need special treatment are the
-        // direct eval calls. These calls are all of the form eval(...), with
-        // no explicit receiver.
-        // These calls are marked as potentially direct eval calls. Whether
-        // they are actually direct calls to eval is determined at run time.
-        VariableProxy* callee = result->AsVariableProxy();
-        if (callee != NULL &&
-            callee->IsVariable(isolate()->factory()->eval_string())) {
-          scope_->DeclarationScope()->RecordEvalCall();
-        }
-        result = factory()->NewCall(result, args, pos);
-        if (fni_ != NULL) fni_->RemoveLastFunction();
-        break;
-      }
-
-      case Token::PERIOD: {
-        Consume(Token::PERIOD);
-        int pos = position();
-        Handle<String> name = ParseIdentifierName(CHECK_OK);
-        result = factory()->NewProperty(
-            result, factory()->NewLiteral(name, pos), pos);
-        if (fni_ != NULL) fni_->PushLiteralName(name);
-        break;
-      }
-
-      default:
-        return result;
-    }
-  }
-}
-
-
 Expression* Parser::ParseMemberWithNewPrefixesExpression(bool* ok) {
   // NewExpression ::
   //   ('new')+ MemberExpression
index 333aaf5..4febdc8 100644 (file)
@@ -490,6 +490,11 @@ class ParserTraits {
   static void CheckAssigningFunctionLiteralToProperty(Expression* left,
                                                       Expression* right);
 
+  // Keep track of eval() calls since they disable all local variable
+  // optimizations. This checks if expression is an eval call, and if yes,
+  // forwards the information to scope.
+  void CheckPossibleEvalCall(Expression* expression, Scope* scope);
+
   // Determine if the expression is a variable proxy and mark it as being used
   // in an assignment or with a increment/decrement operator. This is currently
   // used on for the statically checking assignments to harmony const bindings.
@@ -497,7 +502,7 @@ class ParserTraits {
 
   // Checks LHS expression for assignment and prefix/postfix increment/decrement
   // in strict mode.
-  void CheckStrictModeLValue(Expression*expression, bool* ok);
+  void CheckStrictModeLValue(Expression* expression, bool* ok);
 
   // Returns true if we have a binary expression between two numeric
   // literals. In that case, *x will be changed to an expression which is the
@@ -584,7 +589,7 @@ class ParserTraits {
       int function_token_position,
       FunctionLiteral::FunctionType type,
       bool* ok);
-  Expression* ParseLeftHandSideExpression(bool* ok);
+  Expression* ParseMemberWithNewPrefixesExpression(bool* ok);
 
  private:
   Parser* parser_;
@@ -622,11 +627,6 @@ class Parser : public ParserBase<ParserTraits> {
   // https://codereview.chromium.org/7003030/ ).
   static const int kMaxNumFunctionLocals = 4194303;  // 2^22-1
 
-  enum Mode {
-    PARSE_LAZILY,
-    PARSE_EAGERLY
-  };
-
   enum VariableDeclarationContext {
     kModuleElement,
     kBlockElement,
@@ -640,22 +640,6 @@ class Parser : public ParserBase<ParserTraits> {
     kHasNoInitializers
   };
 
-  class ParsingModeScope BASE_EMBEDDED {
-   public:
-    ParsingModeScope(Parser* parser, Mode mode)
-        : parser_(parser),
-          old_mode_(parser->mode()) {
-      parser_->mode_ = mode;
-    }
-    ~ParsingModeScope() {
-      parser_->mode_ = old_mode_;
-    }
-
-   private:
-    Parser* parser_;
-    Mode old_mode_;
-  };
-
   // Returns NULL if parsing failed.
   FunctionLiteral* ParseProgram();
 
@@ -685,7 +669,6 @@ class Parser : public ParserBase<ParserTraits> {
   }
 
   bool inside_with() const { return scope_->inside_with(); }
-  Mode mode() const { return mode_; }
   ScriptDataImpl** cached_data() const { return cached_data_; }
   CachedDataMode cached_data_mode() const { return cached_data_mode_; }
   Scope* DeclarationScope(VariableMode mode) {
@@ -742,14 +725,10 @@ class Parser : public ParserBase<ParserTraits> {
   // Support for hamony block scoped bindings.
   Block* ParseScopedBlock(ZoneStringList* labels, bool* ok);
 
-  Expression* ParseUnaryExpression(bool* ok);
-  Expression* ParseLeftHandSideExpression(bool* ok);
   Expression* ParseMemberWithNewPrefixesExpression(bool* ok);
   Expression* ParseMemberExpression(bool* ok);
   Expression* ParseMemberExpressionContinuation(Expression* expression,
                                                 bool* ok);
-  Expression* ParseObjectLiteral(bool* ok);
-
   // Initialize the components of a for-in / for-of statement.
   void InitializeForEachStatement(ForEachStatement* stmt,
                                   Expression* each,
@@ -835,8 +814,6 @@ class Parser : public ParserBase<ParserTraits> {
   ScriptDataImpl** cached_data_;
   CachedDataMode cached_data_mode_;
 
-  Mode mode_;
-
   CompilationInfo* info_;
 };
 
index 9480af6..9473701 100644 (file)
@@ -146,8 +146,9 @@ PreParserExpression PreParserTraits::ParseFunctionLiteral(
 }
 
 
-PreParserExpression PreParserTraits::ParseLeftHandSideExpression(bool* ok) {
-  return pre_parser_->ParseLeftHandSideExpression(ok);
+PreParserExpression PreParserTraits::ParseMemberWithNewPrefixesExpression(
+    bool* ok) {
+  return pre_parser_->ParseMemberWithNewPrefixesExpression(ok);
 }
 
 
@@ -842,50 +843,6 @@ PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) {
 #undef DUMMY
 
 
-PreParser::Expression PreParser::ParseLeftHandSideExpression(bool* ok) {
-  // LeftHandSideExpression ::
-  //   (NewExpression | MemberExpression) ...
-
-  Expression result = ParseMemberWithNewPrefixesExpression(CHECK_OK);
-
-  while (true) {
-    switch (peek()) {
-      case Token::LBRACK: {
-        Consume(Token::LBRACK);
-        ParseExpression(true, CHECK_OK);
-        Expect(Token::RBRACK, CHECK_OK);
-        if (result.IsThis()) {
-          result = Expression::ThisProperty();
-        } else {
-          result = Expression::Property();
-        }
-        break;
-      }
-
-      case Token::LPAREN: {
-        ParseArguments(CHECK_OK);
-        result = Expression::Default();
-        break;
-      }
-
-      case Token::PERIOD: {
-        Consume(Token::PERIOD);
-        ParseIdentifierName(CHECK_OK);
-        if (result.IsThis()) {
-          result = Expression::ThisProperty();
-        } else {
-          result = Expression::Property();
-        }
-        break;
-      }
-
-      default:
-        return result;
-    }
-  }
-}
-
-
 PreParser::Expression PreParser::ParseMemberWithNewPrefixesExpression(
     bool* ok) {
   // NewExpression ::
index 7a92347..7977fe2 100644 (file)
@@ -97,6 +97,7 @@ class ParserBase : public Traits {
         extension_(extension),
         fni_(NULL),
         log_(log),
+        mode_(PARSE_EAGERLY),  // Lazy mode must be set explicitly.
         scanner_(scanner),
         stack_limit_(stack_limit),
         stack_overflow_(false),
@@ -138,6 +139,11 @@ class ParserBase : public Traits {
     kDontAllowEvalOrArguments
   };
 
+  enum Mode {
+    PARSE_LAZILY,
+    PARSE_EAGERLY
+  };
+
   // ---------------------------------------------------------------------------
   // FunctionState and BlockState together implement the parser's scope stack.
   // The parser's current scope is in scope_. BlockState and FunctionState
@@ -229,11 +235,28 @@ class ParserBase : public Traits {
     friend class ParserTraits;
   };
 
+  class ParsingModeScope BASE_EMBEDDED {
+   public:
+    ParsingModeScope(ParserBase* parser, Mode mode)
+        : parser_(parser),
+          old_mode_(parser->mode()) {
+      parser_->mode_ = mode;
+    }
+    ~ParsingModeScope() {
+      parser_->mode_ = old_mode_;
+    }
+
+   private:
+    ParserBase* parser_;
+    Mode old_mode_;
+  };
+
   Scanner* scanner() const { return scanner_; }
   int position() { return scanner_->location().beg_pos; }
   int peek_position() { return scanner_->peek_location().beg_pos; }
   bool stack_overflow() const { return stack_overflow_; }
   void set_stack_overflow() { stack_overflow_ = true; }
+  Mode mode() const { return mode_; }
   typename Traits::Type::Zone* zone() const { return zone_; }
 
   INLINE(Token::Value peek()) {
@@ -396,6 +419,7 @@ class ParserBase : public Traits {
   ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
   ExpressionT ParseUnaryExpression(bool* ok);
   ExpressionT ParsePostfixExpression(bool* ok);
+  ExpressionT ParseLeftHandSideExpression(bool* ok);
 
   // Used to detect duplicates in object literals. Each of the values
   // kGetterProperty, kSetterProperty and kValueProperty represents
@@ -462,6 +486,7 @@ class ParserBase : public Traits {
   v8::Extension* extension_;
   FuncNameInferrer* fni_;
   ParserRecorder* log_;
+  Mode mode_;
 
  private:
   Scanner* scanner_;
@@ -585,17 +610,20 @@ class PreParserExpression {
     return IsIdentifier() || IsProperty();
   }
 
+  // At the moment PreParser doesn't track these expression types.
+  bool IsFunctionLiteral() const { return false; }
+  bool IsCall() const { return false; }
+  bool IsCallNew() const { return false; }
+
+  PreParserExpression AsFunctionLiteral() { return *this; }
+
   // Dummy implementation for making expression->somefunc() work in both Parser
   // and PreParser.
   PreParserExpression* operator->() { return this; }
 
-  // These are only used when doing function name inferring, and PreParser
-  // doesn't do function name inferring.
-  void* AsCall() const { return NULL; }
-  void* AsCallNew() const { return NULL; }
-
   // More dummy implementations of things PreParser doesn't need to track:
   void set_index(int index) {}  // For YieldExpressions
+  void set_parenthesized() {}
 
  private:
   // Least significant 2 bits are used as flags. Bits 0 and 1 represent
@@ -673,26 +701,18 @@ class PreParserScope {
 class PreParserFactory {
  public:
   explicit PreParserFactory(void* extra_param) {}
-
-  PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern,
-                                       PreParserIdentifier js_flags,
-                                       int literal_index,
-                                       int pos) {
-    return PreParserExpression::Default();
-  }
-  PreParserExpression NewUnaryOperation(Token::Value op,
-                                        PreParserExpression expression,
-                                        int pos) {
+  PreParserExpression NewLiteral(PreParserIdentifier identifier,
+                                 int pos) {
     return PreParserExpression::Default();
   }
-  PreParserExpression NewBinaryOperation(Token::Value op,
-                                         PreParserExpression left,
-                                         PreParserExpression right, int pos) {
+  PreParserExpression NewNumberLiteral(double number,
+                                       int pos) {
     return PreParserExpression::Default();
   }
-  PreParserExpression NewCompareOperation(Token::Value op,
-                                          PreParserExpression left,
-                                          PreParserExpression right, int pos) {
+  PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern,
+                                       PreParserIdentifier js_flags,
+                                       int literal_index,
+                                       int pos) {
     return PreParserExpression::Default();
   }
   PreParserExpression NewArrayLiteral(PreParserExpressionList values,
@@ -700,18 +720,15 @@ class PreParserFactory {
                                       int pos) {
     return PreParserExpression::Default();
   }
-
   PreParserExpression NewObjectLiteralProperty(bool is_getter,
                                                PreParserExpression value,
                                                int pos) {
     return PreParserExpression::Default();
   }
-
   PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
                                                PreParserExpression value) {
     return PreParserExpression::Default();
   }
-
   PreParserExpression NewObjectLiteral(PreParserExpressionList properties,
                                        int literal_index,
                                        int boilerplate_properties,
@@ -719,48 +736,61 @@ class PreParserFactory {
                                        int pos) {
     return PreParserExpression::Default();
   }
-
-  PreParserExpression NewLiteral(PreParserIdentifier identifier,
-                                 int pos) {
+  PreParserExpression NewVariableProxy(void* generator_variable) {
     return PreParserExpression::Default();
   }
-
-  PreParserExpression NewNumberLiteral(double number,
-                                       int pos) {
+  PreParserExpression NewProperty(PreParserExpression obj,
+                                  PreParserExpression key,
+                                  int pos) {
+    if (obj.IsThis()) {
+      return PreParserExpression::ThisProperty();
+    }
+    return PreParserExpression::Property();
+  }
+  PreParserExpression NewUnaryOperation(Token::Value op,
+                                        PreParserExpression expression,
+                                        int pos) {
+    return PreParserExpression::Default();
+  }
+  PreParserExpression NewBinaryOperation(Token::Value op,
+                                         PreParserExpression left,
+                                         PreParserExpression right, int pos) {
+    return PreParserExpression::Default();
+  }
+  PreParserExpression NewCompareOperation(Token::Value op,
+                                          PreParserExpression left,
+                                          PreParserExpression right, int pos) {
     return PreParserExpression::Default();
   }
-
   PreParserExpression NewAssignment(Token::Value op,
                                     PreParserExpression left,
                                     PreParserExpression right,
                                     int pos) {
     return PreParserExpression::Default();
   }
-
-  PreParserExpression NewVariableProxy(void* generator_variable) {
-    return PreParserExpression::Default();
-  }
-
   PreParserExpression NewYield(PreParserExpression generator_object,
                                PreParserExpression expression,
                                Yield::Kind yield_kind,
                                int pos) {
     return PreParserExpression::Default();
   }
-
   PreParserExpression NewConditional(PreParserExpression condition,
                                      PreParserExpression then_expression,
                                      PreParserExpression else_expression,
                                      int pos) {
     return PreParserExpression::Default();
   }
-
   PreParserExpression NewCountOperation(Token::Value op,
                                         bool is_prefix,
                                         PreParserExpression expression,
                                         int pos) {
     return PreParserExpression::Default();
   }
+  PreParserExpression NewCall(PreParserExpression expression,
+                              PreParserExpressionList arguments,
+                              int pos) {
+    return PreParserExpression::Default();
+  }
 };
 
 
@@ -839,6 +869,10 @@ class PreParserTraits {
   static void CheckAssigningFunctionLiteralToProperty(
       PreParserExpression left, PreParserExpression right) {}
 
+  // PreParser doesn't need to keep track of eval calls.
+  static void CheckPossibleEvalCall(PreParserExpression expression,
+                                    PreParserScope* scope) {}
+
   static PreParserExpression MarkExpressionAsLValue(
       PreParserExpression expression) {
     // TODO(marja): To be able to produce the same errors, the preparser needs
@@ -945,7 +979,7 @@ class PreParserTraits {
       int function_token_position,
       FunctionLiteral::FunctionType type,
       bool* ok);
-  PreParserExpression ParseLeftHandSideExpression(bool* ok);
+  PreParserExpression ParseMemberWithNewPrefixesExpression(bool* ok);
 
  private:
   PreParser* pre_parser_;
@@ -1109,7 +1143,6 @@ class PreParser : public ParserBase<PreParserTraits> {
   Statement ParseTryStatement(bool* ok);
   Statement ParseDebuggerStatement(bool* ok);
   Expression ParseConditionalExpression(bool accept_IN, bool* ok);
-  Expression ParseLeftHandSideExpression(bool* ok);
   Expression ParseMemberExpression(bool* ok);
   Expression ParseMemberExpressionContinuation(PreParserExpression expression,
                                                bool* ok);
@@ -1698,7 +1731,7 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
     if ((op == Token::INIT_VAR
          || op == Token::INIT_CONST_LEGACY
          || op == Token::ASSIGN)
-        && (right->AsCall() == NULL && right->AsCallNew() == NULL)) {
+        && (!right->IsCall() && !right->IsCallNew())) {
       fni_->Infer();
     } else {
       fni_->RemoveLastFunction();
@@ -1890,6 +1923,77 @@ ParserBase<Traits>::ParsePostfixExpression(bool* ok) {
 }
 
 
+template <class Traits>
+typename ParserBase<Traits>::ExpressionT
+ParserBase<Traits>::ParseLeftHandSideExpression(bool* ok) {
+  // LeftHandSideExpression ::
+  //   (NewExpression | MemberExpression) ...
+
+  ExpressionT result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK);
+
+  while (true) {
+    switch (peek()) {
+      case Token::LBRACK: {
+        Consume(Token::LBRACK);
+        int pos = position();
+        ExpressionT index = ParseExpression(true, CHECK_OK);
+        result = factory()->NewProperty(result, index, pos);
+        Expect(Token::RBRACK, CHECK_OK);
+        break;
+      }
+
+      case Token::LPAREN: {
+        int pos;
+        if (scanner()->current_token() == Token::IDENTIFIER) {
+          // For call of an identifier we want to report position of
+          // the identifier as position of the call in the stack trace.
+          pos = position();
+        } else {
+          // For other kinds of calls we record position of the parenthesis as
+          // position of the call. Note that this is extremely important for
+          // expressions of the form function(){...}() for which call position
+          // should not point to the closing brace otherwise it will intersect
+          // with positions recorded for function literal and confuse debugger.
+          pos = peek_position();
+          // Also the trailing parenthesis are a hint that the function will
+          // be called immediately. If we happen to have parsed a preceding
+          // function literal eagerly, we can also compile it eagerly.
+          if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
+            result->AsFunctionLiteral()->set_parenthesized();
+          }
+        }
+        typename Traits::Type::ExpressionList args = ParseArguments(CHECK_OK);
+
+        // Keep track of eval() calls since they disable all local variable
+        // optimizations.
+        // The calls that need special treatment are the
+        // direct eval calls. These calls are all of the form eval(...), with
+        // no explicit receiver.
+        // These calls are marked as potentially direct eval calls. Whether
+        // they are actually direct calls to eval is determined at run time.
+        this->CheckPossibleEvalCall(result, scope_);
+        result = factory()->NewCall(result, args, pos);
+        if (fni_ != NULL) fni_->RemoveLastFunction();
+        break;
+      }
+
+      case Token::PERIOD: {
+        Consume(Token::PERIOD);
+        int pos = position();
+        IdentifierT name = ParseIdentifierName(CHECK_OK);
+        result = factory()->NewProperty(
+            result, factory()->NewLiteral(name, pos), pos);
+        if (fni_ != NULL) this->PushLiteralName(fni_, name);
+        break;
+      }
+
+      default:
+        return result;
+    }
+  }
+}
+
+
 #undef CHECK_OK
 #undef CHECK_OK_CUSTOM