Revision: 20150
Author:   [email protected]
Date:     Fri Mar 21 09:51:33 2014 UTC
Log:      Move ParseLeftHandSideExpression to ParserBase.

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.

[email protected]
BUG=

Review URL: https://codereview.chromium.org/206433003
http://code.google.com/p/v8/source/detail?r=20150

Modified:
 /branches/bleeding_edge/src/parser.cc
 /branches/bleeding_edge/src/parser.h
 /branches/bleeding_edge/src/preparser.cc
 /branches/bleeding_edge/src/preparser.h

=======================================
--- /branches/bleeding_edge/src/parser.cc       Fri Mar 21 09:46:18 2014 UTC
+++ /branches/bleeding_edge/src/parser.cc       Fri Mar 21 09:51:33 2014 UTC
@@ -447,6 +447,16 @@
     right->AsFunctionLiteral()->set_pretenure();
   }
 }
+
+
+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) {
@@ -740,8 +750,8 @@
 }


-Expression* ParserTraits::ParseLeftHandSideExpression(bool* ok) {
-  return parser_->ParseLeftHandSideExpression(ok);
+Expression* ParserTraits::ParseMemberWithNewPrefixesExpression(bool* ok) {
+  return parser_->ParseMemberWithNewPrefixesExpression(ok);
 }


@@ -3041,79 +3051,6 @@
     return loop;
   }
 }
-
-
-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) {
=======================================
--- /branches/bleeding_edge/src/parser.h        Fri Mar 21 09:46:18 2014 UTC
+++ /branches/bleeding_edge/src/parser.h        Fri Mar 21 09:51:33 2014 UTC
@@ -490,6 +490,11 @@
   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 @@

// 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 @@
       int function_token_position,
       FunctionLiteral::FunctionType type,
       bool* ok);
-  Expression* ParseLeftHandSideExpression(bool* ok);
+  Expression* ParseMemberWithNewPrefixesExpression(bool* ok);

  private:
   Parser* parser_;
@@ -622,11 +627,6 @@
   // 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 @@
     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 @@
   }

   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 @@
   // 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 @@
   ScriptDataImpl** cached_data_;
   CachedDataMode cached_data_mode_;

-  Mode mode_;
-
   CompilationInfo* info_;
 };

=======================================
--- /branches/bleeding_edge/src/preparser.cc    Fri Mar 21 09:46:18 2014 UTC
+++ /branches/bleeding_edge/src/preparser.cc    Fri Mar 21 09:51:33 2014 UTC
@@ -146,8 +146,9 @@
 }


-PreParserExpression PreParserTraits::ParseLeftHandSideExpression(bool* ok) {
-  return pre_parser_->ParseLeftHandSideExpression(ok);
+PreParserExpression PreParserTraits::ParseMemberWithNewPrefixesExpression(
+    bool* ok) {
+  return pre_parser_->ParseMemberWithNewPrefixesExpression(ok);
 }


@@ -842,50 +843,6 @@
 #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 ::
=======================================
--- /branches/bleeding_edge/src/preparser.h     Fri Mar 21 09:46:18 2014 UTC
+++ /branches/bleeding_edge/src/preparser.h     Fri Mar 21 09:51:33 2014 UTC
@@ -97,6 +97,7 @@
         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 @@
     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 @@
     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 @@
   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 @@
   v8::Extension* extension_;
   FuncNameInferrer* fni_;
   ParserRecorder* log_;
+  Mode mode_;

  private:
   Scanner* scanner_;
@@ -584,18 +609,21 @@
   bool IsValidLeftHandSide() {
     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,45 +701,34 @@
 class PreParserFactory {
  public:
   explicit PreParserFactory(void* extra_param) {}
-
+  PreParserExpression NewLiteral(PreParserIdentifier identifier,
+                                 int pos) {
+    return PreParserExpression::Default();
+  }
+  PreParserExpression NewNumberLiteral(double number,
+                                       int pos) {
+    return PreParserExpression::Default();
+  }
   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) {
-    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 NewArrayLiteral(PreParserExpressionList values,
                                       int literal_index,
                                       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 @@
                                        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();
+  }
 };


@@ -838,6 +868,10 @@

   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) {
@@ -945,7 +979,7 @@
       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 @@
   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 @@
     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();
@@ -1888,6 +1921,77 @@
   }
   return expression;
 }
+
+
+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

--
--
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/d/optout.

Reply via email to