Revision: 17202
Author:   [email protected]
Date:     Mon Oct 14 16:46:51 2013 UTC
Log: Introduce ParserBase for common code between parser and pre-parser.

[email protected]

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

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       Mon Oct 14 13:07:20 2013 UTC
+++ /branches/bleeding_edge/src/parser.cc       Mon Oct 14 16:46:51 2013 UTC
@@ -536,7 +536,8 @@
 // Implementation of Parser

 Parser::Parser(CompilationInfo* info)
-    : isolate_(info->isolate()),
+    : ParserBase(&scanner_, info->isolate()->stack_guard()->real_climit()),
+      isolate_(info->isolate()),
       symbol_cache_(0, info->zone()),
       script_(info->script()),
       scanner_(isolate_->unicode_cache()),
@@ -548,11 +549,6 @@
       extension_(info->extension()),
       pre_parse_data_(NULL),
       fni_(NULL),
-      allow_natives_syntax_(false),
-      allow_lazy_(false),
-      allow_generators_(false),
-      allow_for_of_(false),
-      stack_overflow_(false),
       parenthesized_function_(false),
       zone_(info->zone()),
       info_(info) {
@@ -690,7 +686,7 @@
       result->set_ast_properties(factory()->visitor()->ast_properties());
       result->set_dont_optimize_reason(
           factory()->visitor()->dont_optimize_reason());
-    } else if (stack_overflow_) {
+    } else if (stack_overflow()) {
       isolate()->StackOverflow();
     }
   }
@@ -787,7 +783,7 @@
   ASSERT(target_stack_ == NULL);

   if (result == NULL) {
-    if (stack_overflow_) isolate()->StackOverflow();
+    if (stack_overflow()) isolate()->StackOverflow();
   } else {
     Handle<String> inferred_name(shared_info->inferred_name());
     result->set_inferred_name(inferred_name);
@@ -3484,7 +3480,7 @@
   // We don't report stack overflows here, to avoid increasing the
   // stack depth even further.  Instead we report it after parsing is
   // over, in ParseProgram/ParseJson.
-  if (token == Token::ILLEGAL && stack_overflow_) return;
+  if (token == Token::ILLEGAL && stack_overflow()) return;
   // Four of the tokens are treated specially
   switch (token) {
     case Token::EOS:
@@ -4378,7 +4374,7 @@
PreParser::PreParseResult result = LazyParseFunctionLiteral(&logger);
         if (result == PreParser::kPreParseStackOverflow) {
           // Propagate stack overflow.
-          stack_overflow_ = true;
+          set_stack_overflow();
           *ok = false;
           return NULL;
         }
@@ -4613,39 +4609,13 @@
 }


-bool Parser::peek_any_identifier() {
+bool ParserBase::peek_any_identifier() {
   Token::Value next = peek();
   return next == Token::IDENTIFIER ||
          next == Token::FUTURE_RESERVED_WORD ||
          next == Token::FUTURE_STRICT_RESERVED_WORD ||
          next == Token::YIELD;
 }
-
-
-void Parser::Consume(Token::Value token) {
-  Token::Value next = Next();
-  USE(next);
-  USE(token);
-  ASSERT(next == token);
-}
-
-
-void Parser::Expect(Token::Value token, bool* ok) {
-  Token::Value next = Next();
-  if (next == token) return;
-  ReportUnexpectedToken(next);
-  *ok = false;
-}
-
-
-bool Parser::Check(Token::Value token) {
-  Token::Value next = peek();
-  if (next == token) {
-    Consume(next);
-    return true;
-  }
-  return false;
-}


 bool Parser::CheckContextualKeyword(Vector<const char> keyword) {
@@ -4658,7 +4628,7 @@
 }


-void Parser::ExpectSemicolon(bool* ok) {
+void ParserBase::ExpectSemicolon(bool* ok) {
   // Check for automatic semicolon insertion according to
   // the rules given in ECMA-262, section 7.9, page 21.
   Token::Value tok = peek();
@@ -4666,7 +4636,7 @@
     Next();
     return;
   }
-  if (scanner().HasAnyLineTerminatorBeforeNext() ||
+  if (scanner()->HasAnyLineTerminatorBeforeNext() ||
       tok == Token::RBRACE ||
       tok == Token::EOS) {
     return;
=======================================
--- /branches/bleeding_edge/src/parser.h        Mon Oct 14 13:07:20 2013 UTC
+++ /branches/bleeding_edge/src/parser.h        Mon Oct 14 16:46:51 2013 UTC
@@ -425,35 +425,13 @@
 // Forward declaration.
 class SingletonLogger;

-class Parser BASE_EMBEDDED {
+class Parser : public ParserBase {
  public:
   explicit Parser(CompilationInfo* info);
   ~Parser() {
     delete reusable_preparser_;
     reusable_preparser_ = NULL;
   }
-
-  bool allow_natives_syntax() const { return allow_natives_syntax_; }
-  bool allow_lazy() const { return allow_lazy_; }
-  bool allow_modules() { return scanner().HarmonyModules(); }
-  bool allow_harmony_scoping() { return scanner().HarmonyScoping(); }
-  bool allow_generators() const { return allow_generators_; }
-  bool allow_for_of() const { return allow_for_of_; }
-  bool allow_harmony_numeric_literals() {
-    return scanner().HarmonyNumericLiterals();
-  }
-
- void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; }
-  void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
- void set_allow_modules(bool allow) { scanner().SetHarmonyModules(allow); }
-  void set_allow_harmony_scoping(bool allow) {
-    scanner().SetHarmonyScoping(allow);
-  }
-  void set_allow_generators(bool allow) { allow_generators_ = allow; }
-  void set_allow_for_of(bool allow) { allow_for_of_ = allow; }
-  void set_allow_harmony_numeric_literals(bool allow) {
-    scanner().SetHarmonyNumericLiterals(allow);
-  }

// Parses the source code represented by the compilation info and sets its
   // function literal.  Returns false (and deallocates any allocated AST
@@ -712,37 +690,10 @@
   // Magical syntax support.
   Expression* ParseV8Intrinsic(bool* ok);

-  INLINE(Token::Value peek()) {
-    if (stack_overflow_) return Token::ILLEGAL;
-    return scanner().peek();
-  }
-
-  INLINE(Token::Value Next()) {
-    // BUG 1215673: Find a thread safe way to set a stack limit in
-    // pre-parse mode. Otherwise, we cannot safely pre-parse from other
-    // threads.
-    if (stack_overflow_) {
-      return Token::ILLEGAL;
-    }
-    if (StackLimitCheck(isolate()).HasOverflowed()) {
-      // Any further calls to Next or peek will return the illegal token.
-      // The current call must return the next token, which might already
-      // have been peek'ed.
-      stack_overflow_ = true;
-    }
-    return scanner().Next();
-  }
-
bool is_generator() const { return current_function_state_->is_generator(); }

bool CheckInOrOf(bool accept_OF, ForEachStatement::VisitMode* visit_mode);

-  bool peek_any_identifier();
-
-  INLINE(void Consume(Token::Value token));
-  void Expect(Token::Value token, bool* ok);
-  bool Check(Token::Value token);
-  void ExpectSemicolon(bool* ok);
   bool CheckContextualKeyword(Vector<const char> keyword);
   void ExpectContextualKeyword(Vector<const char> keyword, bool* ok);

@@ -865,11 +816,6 @@
   FuncNameInferrer* fni_;

   Mode mode_;
-  bool allow_natives_syntax_;
-  bool allow_lazy_;
-  bool allow_generators_;
-  bool allow_for_of_;
-  bool stack_overflow_;
   // If true, the next (and immediately following) function literal is
   // preceded by a parenthesis.
   // Heuristically that means that the function will be called immediately,
=======================================
--- /branches/bleeding_edge/src/preparser.cc    Mon Oct 14 13:07:20 2013 UTC
+++ /branches/bleeding_edge/src/preparser.cc    Mon Oct 14 16:46:51 2013 UTC
@@ -63,17 +63,17 @@
   set_language_mode(mode);
   Scope function_scope(&scope_, kFunctionScope);
   function_scope.set_is_generator(is_generator);
-  ASSERT_EQ(i::Token::LBRACE, scanner_->current_token());
+  ASSERT_EQ(i::Token::LBRACE, scanner()->current_token());
   bool ok = true;
-  int start_position = scanner_->peek_location().beg_pos;
+  int start_position = scanner()->peek_location().beg_pos;
   ParseLazyFunctionLiteralBody(&ok);
-  if (stack_overflow_) return kPreParseStackOverflow;
+  if (stack_overflow()) return kPreParseStackOverflow;
   if (!ok) {
-    ReportUnexpectedToken(scanner_->current_token());
+    ReportUnexpectedToken(scanner()->current_token());
   } else {
-    ASSERT_EQ(i::Token::RBRACE, scanner_->peek());
+    ASSERT_EQ(i::Token::RBRACE, scanner()->peek());
     if (!is_classic_mode()) {
-      int end_pos = scanner_->location().end_pos;
+      int end_pos = scanner()->location().end_pos;
       CheckOctalLiteral(start_position, end_pos, &ok);
       if (ok) {
         CheckDelayedStrictModeViolation(start_position, end_pos, &ok);
@@ -101,10 +101,10 @@
   // We don't report stack overflows here, to avoid increasing the
   // stack depth even further.  Instead we report it after parsing is
   // over, in ParseProgram.
-  if (token == i::Token::ILLEGAL && stack_overflow_) {
+  if (token == i::Token::ILLEGAL && stack_overflow()) {
     return;
   }
-  i::Scanner::Location source_location = scanner_->location();
+  i::Scanner::Location source_location = scanner()->location();

   // Four of the tokens are treated specially
   switch (token) {
@@ -132,10 +132,10 @@
 // Checks whether octal literal last seen is between beg_pos and end_pos.
 // If so, reports an error.
 void PreParser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) {
-  i::Scanner::Location octal = scanner_->octal_position();
+  i::Scanner::Location octal = scanner()->octal_position();
   if (beg_pos <= octal.beg_pos && octal.end_pos <= end_pos) {
     ReportMessageAt(octal, "strict_octal_literal", NULL);
-    scanner_->clear_octal_position();
+    scanner()->clear_octal_position();
     *ok = false;
   }
 }
@@ -274,9 +274,9 @@
       return ParseTryStatement(ok);

     case i::Token::FUNCTION: {
-      i::Scanner::Location start_location = scanner_->peek_location();
+      i::Scanner::Location start_location = scanner()->peek_location();
       Statement statement = ParseFunctionDeclaration(CHECK_OK);
-      i::Scanner::Location end_location = scanner_->location();
+      i::Scanner::Location end_location = scanner()->location();
       if (!is_classic_mode()) {
         ReportMessageAt(start_location.beg_pos, end_location.end_pos,
                         "strict_function", NULL);
@@ -304,9 +304,9 @@
   //      '{' FunctionBody '}'
   Expect(i::Token::FUNCTION, CHECK_OK);

-  bool is_generator = allow_generators_ && Check(i::Token::MUL);
+  bool is_generator = allow_generators() && Check(i::Token::MUL);
   Identifier identifier = ParseIdentifier(CHECK_OK);
-  i::Scanner::Location location = scanner_->location();
+  i::Scanner::Location location = scanner()->location();

   Expression function_value = ParseFunctionLiteral(is_generator, CHECK_OK);

@@ -402,7 +402,7 @@
       case i::CLASSIC_MODE:
         break;
       case i::STRICT_MODE: {
-        i::Scanner::Location location = scanner_->peek_location();
+        i::Scanner::Location location = scanner()->peek_location();
         ReportMessageAt(location, "strict_const", NULL);
         *ok = false;
         return Statement::Default();
@@ -410,7 +410,7 @@
       case i::EXTENDED_MODE:
         if (var_context != kSourceElement &&
             var_context != kForStatement) {
-          i::Scanner::Location location = scanner_->peek_location();
+          i::Scanner::Location location = scanner()->peek_location();
           ReportMessageAt(location.beg_pos, location.end_pos,
                           "unprotected_const", NULL);
           *ok = false;
@@ -427,7 +427,7 @@
// * It is a Syntax Error if the code that matches this production is not
     //   contained in extended code.
     if (!is_extended_mode()) {
-      i::Scanner::Location location = scanner_->peek_location();
+      i::Scanner::Location location = scanner()->peek_location();
       ReportMessageAt(location.beg_pos, location.end_pos,
                       "illegal_let", NULL);
       *ok = false;
@@ -436,7 +436,7 @@
     Consume(i::Token::LET);
     if (var_context != kSourceElement &&
         var_context != kForStatement) {
-      i::Scanner::Location location = scanner_->peek_location();
+      i::Scanner::Location location = scanner()->peek_location();
       ReportMessageAt(location.beg_pos, location.end_pos,
                       "unprotected_let", NULL);
       *ok = false;
@@ -457,7 +457,7 @@
     if (nvars > 0) Consume(i::Token::COMMA);
     Identifier identifier  = ParseIdentifier(CHECK_OK);
     if (!is_classic_mode() && !identifier.IsValidStrictVariable()) {
-      StrictModeIdentifierViolation(scanner_->location(),
+      StrictModeIdentifierViolation(scanner()->location(),
                                     "strict_var_name",
                                     identifier,
                                     ok);
@@ -524,7 +524,7 @@

   Expect(i::Token::CONTINUE, CHECK_OK);
   i::Token::Value tok = peek();
-  if (!scanner_->HasAnyLineTerminatorBeforeNext() &&
+  if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
       tok != i::Token::SEMICOLON &&
       tok != i::Token::RBRACE &&
       tok != i::Token::EOS) {
@@ -541,7 +541,7 @@

   Expect(i::Token::BREAK, CHECK_OK);
   i::Token::Value tok = peek();
-  if (!scanner_->HasAnyLineTerminatorBeforeNext() &&
+  if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
       tok != i::Token::SEMICOLON &&
       tok != i::Token::RBRACE &&
       tok != i::Token::EOS) {
@@ -567,7 +567,7 @@
   // This is not handled during preparsing.

   i::Token::Value tok = peek();
-  if (!scanner_->HasAnyLineTerminatorBeforeNext() &&
+  if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
       tok != i::Token::SEMICOLON &&
       tok != i::Token::RBRACE &&
       tok != i::Token::EOS) {
@@ -583,7 +583,7 @@
   //   'with' '(' Expression ')' Statement
   Expect(i::Token::WITH, CHECK_OK);
   if (!is_classic_mode()) {
-    i::Scanner::Location location = scanner_->location();
+    i::Scanner::Location location = scanner()->location();
     ReportMessageAt(location, "strict_mode_with", NULL);
     *ok = false;
     return Statement::Default();
@@ -661,7 +661,7 @@
 bool PreParser::CheckInOrOf(bool accept_OF) {
   if (peek() == i::Token::IN ||
       (allow_for_of() && accept_OF && peek() == i::Token::IDENTIFIER &&
- scanner_->is_next_contextual_keyword(v8::internal::CStrVector("of")))) { + scanner()->is_next_contextual_keyword(v8::internal::CStrVector("of")))) {
     Next();
     return true;
   }
@@ -728,8 +728,8 @@
   //   'throw' [no line terminator] Expression ';'

   Expect(i::Token::THROW, CHECK_OK);
-  if (scanner_->HasAnyLineTerminatorBeforeNext()) {
-    i::Scanner::Location pos = scanner_->location();
+  if (scanner()->HasAnyLineTerminatorBeforeNext()) {
+    i::Scanner::Location pos = scanner()->location();
     ReportMessageAt(pos, "newline_after_throw", NULL);
     *ok = false;
     return Statement::Default();
@@ -765,7 +765,7 @@
     Expect(i::Token::LPAREN, CHECK_OK);
     Identifier id = ParseIdentifier(CHECK_OK);
     if (!is_classic_mode() && !id.IsValidStrictVariable()) {
-      StrictModeIdentifierViolation(scanner_->location(),
+      StrictModeIdentifierViolation(scanner()->location(),
                                     "strict_catch_variable",
                                     id,
                                     ok);
@@ -838,7 +838,7 @@
     return ParseYieldExpression(ok);
   }

-  i::Scanner::Location before = scanner_->peek_location();
+  i::Scanner::Location before = scanner()->peek_location();
   Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK);

   if (!i::Token::IsAssignmentOp(peek())) {
@@ -849,7 +849,7 @@
   if (!is_classic_mode() &&
       expression.IsIdentifier() &&
       expression.AsIdentifier().IsEvalOrArguments()) {
-    i::Scanner::Location after = scanner_->location();
+    i::Scanner::Location after = scanner()->location();
     ReportMessageAt(before.beg_pos, after.end_pos,
                     "strict_lhs_assignment", NULL);
     *ok = false;
@@ -946,12 +946,12 @@
     return Expression::Default();
   } else if (i::Token::IsCountOp(op)) {
     op = Next();
-    i::Scanner::Location before = scanner_->peek_location();
+    i::Scanner::Location before = scanner()->peek_location();
     Expression expression = ParseUnaryExpression(CHECK_OK);
     if (!is_classic_mode() &&
         expression.IsIdentifier() &&
         expression.AsIdentifier().IsEvalOrArguments()) {
-      i::Scanner::Location after = scanner_->location();
+      i::Scanner::Location after = scanner()->location();
       ReportMessageAt(before.beg_pos, after.end_pos,
                       "strict_lhs_prefix", NULL);
       *ok = false;
@@ -967,14 +967,14 @@
   // PostfixExpression ::
   //   LeftHandSideExpression ('++' | '--')?

-  i::Scanner::Location before = scanner_->peek_location();
+  i::Scanner::Location before = scanner()->peek_location();
   Expression expression = ParseLeftHandSideExpression(CHECK_OK);
-  if (!scanner_->HasAnyLineTerminatorBeforeNext() &&
+  if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
       i::Token::IsCountOp(peek())) {
     if (!is_classic_mode() &&
         expression.IsIdentifier() &&
         expression.AsIdentifier().IsEvalOrArguments()) {
-      i::Scanner::Location after = scanner_->location();
+      i::Scanner::Location after = scanner()->location();
       ReportMessageAt(before.beg_pos, after.end_pos,
                       "strict_lhs_postfix", NULL);
       *ok = false;
@@ -1074,14 +1074,14 @@
   if (peek() == i::Token::FUNCTION) {
     Consume(i::Token::FUNCTION);

-    bool is_generator = allow_generators_ && Check(i::Token::MUL);
+    bool is_generator = allow_generators() && Check(i::Token::MUL);
     Identifier identifier = Identifier::Default();
     if (peek_any_identifier()) {
       identifier = ParseIdentifier(CHECK_OK);
     }
     result = ParseFunctionLiteral(is_generator, CHECK_OK);
     if (result.IsStrictFunction() && !identifier.IsValidStrictVariable()) {
-      StrictModeIdentifierViolation(scanner_->location(),
+      StrictModeIdentifierViolation(scanner()->location(),
                                     "strict_function_name",
                                     identifier,
                                     ok);
@@ -1238,7 +1238,7 @@
// | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
   //    )*[','] '}'

- i::ObjectLiteralChecker<PreParser> checker(this, scanner_, language_mode()); + i::ObjectLiteralChecker<PreParser> checker(this, scanner(), language_mode());

   Expect(i::Token::LBRACE, CHECK_OK);
   while (peek() != i::Token::RBRACE) {
@@ -1312,18 +1312,18 @@

 PreParser::Expression PreParser::ParseRegExpLiteral(bool seen_equal,
                                                     bool* ok) {
-  if (!scanner_->ScanRegExpPattern(seen_equal)) {
+  if (!scanner()->ScanRegExpPattern(seen_equal)) {
     Next();
-    ReportMessageAt(scanner_->location(), "unterminated_regexp", NULL);
+    ReportMessageAt(scanner()->location(), "unterminated_regexp", NULL);
     *ok = false;
     return Expression::Default();
   }

   scope_->NextMaterializedLiteralIndex();

-  if (!scanner_->ScanRegExpFlags()) {
+  if (!scanner()->ScanRegExpFlags()) {
     Next();
-    ReportMessageAt(scanner_->location(), "invalid_regexp_flags", NULL);
+    ReportMessageAt(scanner()->location(), "invalid_regexp_flags", NULL);
     *ok = false;
     return Expression::Default();
   }
@@ -1368,28 +1368,28 @@
   //  FormalParameterList ::
   //    '(' (Identifier)*[','] ')'
   Expect(i::Token::LPAREN, CHECK_OK);
-  int start_position = scanner_->location().beg_pos;
+  int start_position = scanner()->location().beg_pos;
   bool done = (peek() == i::Token::RPAREN);
-  i::DuplicateFinder duplicate_finder(scanner_->unicode_cache());
+  i::DuplicateFinder duplicate_finder(scanner()->unicode_cache());
   while (!done) {
     Identifier id = ParseIdentifier(CHECK_OK);
     if (!id.IsValidStrictVariable()) {
-      StrictModeIdentifierViolation(scanner_->location(),
+      StrictModeIdentifierViolation(scanner()->location(),
                                     "strict_param_name",
                                     id,
                                     CHECK_OK);
     }
     int prev_value;
-    if (scanner_->is_literal_ascii()) {
+    if (scanner()->is_literal_ascii()) {
       prev_value =
- duplicate_finder.AddAsciiSymbol(scanner_->literal_ascii_string(), 1); + duplicate_finder.AddAsciiSymbol(scanner()->literal_ascii_string(), 1);
     } else {
       prev_value =
- duplicate_finder.AddUtf16Symbol(scanner_->literal_utf16_string(), 1); + duplicate_finder.AddUtf16Symbol(scanner()->literal_utf16_string(), 1);
     }

     if (prev_value != 0) {
-      SetStrictModeViolation(scanner_->location(),
+      SetStrictModeViolation(scanner()->location(),
                              "strict_param_dupe",
                              CHECK_OK);
     }
@@ -1404,7 +1404,7 @@
   // Currently only happens to top-level functions.
// Optimistically assume that all top-level functions are lazily compiled.
   bool is_lazily_compiled = (outer_scope_type == kTopLevelScope &&
-                             !inside_with && allow_lazy_ &&
+                             !inside_with && allow_lazy() &&
                              !parenthesized_function_);
   parenthesized_function_ = false;

@@ -1417,7 +1417,7 @@
   Expect(i::Token::RBRACE, CHECK_OK);

   if (!is_classic_mode()) {
-    int end_position = scanner_->location().end_pos;
+    int end_position = scanner()->location().end_pos;
     CheckOctalLiteral(start_position, end_position, CHECK_OK);
CheckDelayedStrictModeViolation(start_position, end_position, CHECK_OK);
     return Expression::StrictFunction();
@@ -1428,15 +1428,15 @@


 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) {
-  int body_start = scanner_->location().beg_pos;
+  int body_start = scanner()->location().beg_pos;
   log_->PauseRecording();
   ParseSourceElements(i::Token::RBRACE, ok);
   log_->ResumeRecording();
   if (!*ok) return;

   // Position right after terminal '}'.
-  ASSERT_EQ(i::Token::RBRACE, scanner_->peek());
-  int body_end = scanner_->peek_location().end_pos;
+  ASSERT_EQ(i::Token::RBRACE, scanner()->peek());
+  int body_end = scanner()->peek_location().end_pos;
   log_->LogFunction(body_start, body_end,
                     scope_->materialized_literal_count(),
                     scope_->expected_properties(),
@@ -1448,7 +1448,7 @@
   // CallRuntime ::
   //   '%' Identifier Arguments
   Expect(i::Token::MOD, CHECK_OK);
-  if (!allow_natives_syntax_) {
+  if (!allow_natives_syntax()) {
     *ok = false;
     return Expression::Default();
   }
@@ -1461,29 +1461,12 @@
 #undef CHECK_OK


-void PreParser::ExpectSemicolon(bool* ok) {
-  // Check for automatic semicolon insertion according to
-  // the rules given in ECMA-262, section 7.9, page 21.
-  i::Token::Value tok = peek();
-  if (tok == i::Token::SEMICOLON) {
-    Next();
-    return;
-  }
-  if (scanner_->HasAnyLineTerminatorBeforeNext() ||
-      tok == i::Token::RBRACE ||
-      tok == i::Token::EOS) {
-    return;
-  }
-  Expect(i::Token::SEMICOLON, ok);
-}
-
-
 void PreParser::LogSymbol() {
-  int identifier_pos = scanner_->location().beg_pos;
-  if (scanner_->is_literal_ascii()) {
-    log_->LogAsciiSymbol(identifier_pos, scanner_->literal_ascii_string());
+  int identifier_pos = scanner()->location().beg_pos;
+  if (scanner()->is_literal_ascii()) {
+ log_->LogAsciiSymbol(identifier_pos, scanner()->literal_ascii_string());
   } else {
-    log_->LogUtf16Symbol(identifier_pos, scanner_->literal_utf16_string());
+ log_->LogUtf16Symbol(identifier_pos, scanner()->literal_utf16_string());
   }
 }

@@ -1492,10 +1475,10 @@
   const int kUseStrictLength = 10;
   const char* kUseStrictChars = "use strict";
   LogSymbol();
-  if (scanner_->is_literal_ascii() &&
-      scanner_->literal_length() == kUseStrictLength &&
-      !scanner_->literal_contains_escapes() &&
-      !strncmp(scanner_->literal_ascii_string().start(), kUseStrictChars,
+  if (scanner()->is_literal_ascii() &&
+      scanner()->literal_length() == kUseStrictLength &&
+      !scanner()->literal_contains_escapes() &&
+      !strncmp(scanner()->literal_ascii_string().start(), kUseStrictChars,
                kUseStrictLength)) {
     return Expression::UseStrictStringLiteral();
   }
@@ -1505,22 +1488,22 @@

 PreParser::Identifier PreParser::GetIdentifierSymbol() {
   LogSymbol();
-  if (scanner_->current_token() == i::Token::FUTURE_RESERVED_WORD) {
+  if (scanner()->current_token() == i::Token::FUTURE_RESERVED_WORD) {
     return Identifier::FutureReserved();
-  } else if (scanner_->current_token() ==
+  } else if (scanner()->current_token() ==
              i::Token::FUTURE_STRICT_RESERVED_WORD) {
     return Identifier::FutureStrictReserved();
-  } else if (scanner_->current_token() == i::Token::YIELD) {
+  } else if (scanner()->current_token() == i::Token::YIELD) {
     return Identifier::Yield();
   }
-  if (scanner_->is_literal_ascii()) {
+  if (scanner()->is_literal_ascii()) {
     // Detect strict-mode poison words.
-    if (scanner_->literal_length() == 4 &&
-        !strncmp(scanner_->literal_ascii_string().start(), "eval", 4)) {
+    if (scanner()->literal_length() == 4 &&
+        !strncmp(scanner()->literal_ascii_string().start(), "eval", 4)) {
       return Identifier::Eval();
     }
-    if (scanner_->literal_length() == 9 &&
- !strncmp(scanner_->literal_ascii_string().start(), "arguments", 9)) {
+    if (scanner()->literal_length() == 9 &&
+ !strncmp(scanner()->literal_ascii_string().start(), "arguments", 9)) {
       return Identifier::Arguments();
     }
   }
@@ -1532,7 +1515,7 @@
   i::Token::Value next = Next();
   switch (next) {
     case i::Token::FUTURE_RESERVED_WORD: {
-      i::Scanner::Location location = scanner_->location();
+      i::Scanner::Location location = scanner()->location();
       ReportMessageAt(location.beg_pos, location.end_pos,
                       "reserved_word", NULL);
       *ok = false;
@@ -1541,14 +1524,14 @@
     case i::Token::YIELD:
       if (scope_->is_generator()) {
// 'yield' in a generator is only valid as part of a YieldExpression.
-        ReportMessageAt(scanner_->location(), "unexpected_token", "yield");
+ ReportMessageAt(scanner()->location(), "unexpected_token", "yield");
         *ok = false;
         return Identifier::Yield();
       }
       // FALLTHROUGH
     case i::Token::FUTURE_STRICT_RESERVED_WORD:
       if (!is_classic_mode()) {
-        i::Scanner::Location location = scanner_->location();
+        i::Scanner::Location location = scanner()->location();
         ReportMessageAt(location.beg_pos, location.end_pos,
                         "strict_reserved_word", NULL);
         *ok = false;
@@ -1619,7 +1602,7 @@
 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) {
   i::Token::Value next = Next();
   if (i::Token::IsKeyword(next)) {
-    int pos = scanner_->location().beg_pos;
+    int pos = scanner()->location().beg_pos;
     const char* keyword = i::Token::String(next);
     log_->LogAsciiSymbol(pos, i::Vector<const char>(keyword,
i::StrLength(keyword)));
@@ -1644,22 +1627,14 @@
                                                                bool* ok) {
   Identifier result = ParseIdentifierName(ok);
   if (!*ok) return Identifier::Default();
-  if (scanner_->is_literal_ascii() &&
-      scanner_->literal_length() == 3) {
-    const char* token = scanner_->literal_ascii_string().start();
+  if (scanner()->is_literal_ascii() &&
+      scanner()->literal_length() == 3) {
+    const char* token = scanner()->literal_ascii_string().start();
     *is_get = strncmp(token, "get", 3) == 0;
     *is_set = !*is_get && strncmp(token, "set", 3) == 0;
   }
   return result;
 }

-
-bool PreParser::peek_any_identifier() {
-  i::Token::Value next = peek();
-  return next == i::Token::IDENTIFIER ||
-         next == i::Token::FUTURE_RESERVED_WORD ||
-         next == i::Token::FUTURE_STRICT_RESERVED_WORD ||
-         next == i::Token::YIELD;
-}

 } }  // v8::internal
=======================================
--- /branches/bleeding_edge/src/preparser.h     Mon Oct 14 13:07:20 2013 UTC
+++ /branches/bleeding_edge/src/preparser.h     Mon Oct 14 16:46:51 2013 UTC
@@ -123,6 +123,112 @@
     *ok = false;
   }
 }
+
+
+// Common base class shared between parser and pre-parser.
+class ParserBase {
+ public:
+  ParserBase(Scanner* scanner, uintptr_t stack_limit)
+      : scanner_(scanner),
+        stack_limit_(stack_limit),
+        stack_overflow_(false),
+        allow_lazy_(false),
+        allow_natives_syntax_(false),
+        allow_generators_(false),
+        allow_for_of_(false) { }
+ // TODO(mstarzinger): Only virtual until message reporting has been unified.
+  virtual ~ParserBase() { }
+
+  // Getters that indicate whether certain syntactical constructs are
+  // allowed to be parsed by this instance of the parser.
+  bool allow_lazy() const { return allow_lazy_; }
+  bool allow_natives_syntax() const { return allow_natives_syntax_; }
+  bool allow_generators() const { return allow_generators_; }
+  bool allow_for_of() const { return allow_for_of_; }
+  bool allow_modules() const { return scanner()->HarmonyModules(); }
+ bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); }
+  bool allow_harmony_numeric_literals() const {
+    return scanner()->HarmonyNumericLiterals();
+  }
+
+  // Setters that determine whether certain syntactical constructs are
+  // allowed to be parsed by this instance of the parser.
+  void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
+ void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; }
+  void set_allow_generators(bool allow) { allow_generators_ = allow; }
+  void set_allow_for_of(bool allow) { allow_for_of_ = allow; }
+ void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); }
+  void set_allow_harmony_scoping(bool allow) {
+    scanner()->SetHarmonyScoping(allow);
+  }
+  void set_allow_harmony_numeric_literals(bool allow) {
+    scanner()->SetHarmonyNumericLiterals(allow);
+  }
+
+ protected:
+  Scanner* scanner() const { return scanner_; }
+  bool stack_overflow() const { return stack_overflow_; }
+  void set_stack_overflow() { stack_overflow_ = true; }
+
+  INLINE(Token::Value peek()) {
+    if (stack_overflow_) return Token::ILLEGAL;
+    return scanner()->peek();
+  }
+
+  INLINE(Token::Value Next()) {
+    if (stack_overflow_) return Token::ILLEGAL;
+    {
+      int marker;
+      if (reinterpret_cast<uintptr_t>(&marker) < stack_limit_) {
+        // Any further calls to Next or peek will return the illegal token.
+        // The current call must return the next token, which might already
+        // have been peek'ed.
+        stack_overflow_ = true;
+      }
+    }
+    return scanner()->Next();
+  }
+
+  void Consume(Token::Value token) {
+    Token::Value next = Next();
+    USE(next);
+    USE(token);
+    ASSERT(next == token);
+  }
+
+  bool Check(Token::Value token) {
+    Token::Value next = peek();
+    if (next == token) {
+      Consume(next);
+      return true;
+    }
+    return false;
+  }
+
+  void Expect(Token::Value token, bool* ok) {
+    Token::Value next = Next();
+    if (next != token) {
+      ReportUnexpectedToken(next);
+      *ok = false;
+    }
+  }
+
+  bool peek_any_identifier();
+  void ExpectSemicolon(bool* ok);
+
+  // Report syntax errors.
+  virtual void ReportUnexpectedToken(Token::Value token) = 0;
+
+ private:
+  Scanner* scanner_;
+  uintptr_t stack_limit_;
+  bool stack_overflow_;
+
+  bool allow_lazy_;
+  bool allow_natives_syntax_;
+  bool allow_generators_;
+  bool allow_for_of_;
+};


// Preparsing checks a JavaScript program and emits preparse-data that helps
@@ -141,7 +247,7 @@
 typedef uint8_t byte;
 namespace i = v8::internal;

-class PreParser {
+class PreParser : public ParserBase {
  public:
   enum PreParseResult {
     kPreParseStackOverflow,
@@ -152,42 +258,14 @@
   PreParser(i::Scanner* scanner,
             i::ParserRecorder* log,
             uintptr_t stack_limit)
-      : scanner_(scanner),
+      : ParserBase(scanner, stack_limit),
         log_(log),
         scope_(NULL),
-        stack_limit_(stack_limit),
         strict_mode_violation_location_(i::Scanner::Location::invalid()),
         strict_mode_violation_type_(NULL),
-        stack_overflow_(false),
-        allow_lazy_(false),
-        allow_natives_syntax_(false),
-        allow_generators_(false),
-        allow_for_of_(false),
         parenthesized_function_(false) { }

   ~PreParser() {}
-
-  bool allow_natives_syntax() const { return allow_natives_syntax_; }
-  bool allow_lazy() const { return allow_lazy_; }
-  bool allow_modules() const { return scanner_->HarmonyModules(); }
-  bool allow_harmony_scoping() const { return scanner_->HarmonyScoping(); }
-  bool allow_generators() const { return allow_generators_; }
-  bool allow_for_of() const { return allow_for_of_; }
-  bool allow_harmony_numeric_literals() const {
-    return scanner_->HarmonyNumericLiterals();
-  }
-
- void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; }
-  void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
- void set_allow_modules(bool allow) { scanner_->SetHarmonyModules(allow); }
-  void set_allow_harmony_scoping(bool allow) {
-    scanner_->SetHarmonyScoping(allow);
-  }
-  void set_allow_generators(bool allow) { allow_generators_ = allow; }
-  void set_allow_for_of(bool allow) { allow_for_of_ = allow; }
-  void set_allow_harmony_numeric_literals(bool allow) {
-    scanner_->SetHarmonyNumericLiterals(allow);
-  }

   // Pre-parse the program from the character stream; returns true on
   // success (even if parsing failed, the pre-parse data successfully
@@ -196,13 +274,13 @@
   PreParseResult PreParseProgram() {
     Scope top_scope(&scope_, kTopLevelScope);
     bool ok = true;
-    int start_position = scanner_->peek_location().beg_pos;
+    int start_position = scanner()->peek_location().beg_pos;
     ParseSourceElements(i::Token::EOS, &ok);
-    if (stack_overflow_) return kPreParseStackOverflow;
+    if (stack_overflow()) return kPreParseStackOverflow;
     if (!ok) {
-      ReportUnexpectedToken(scanner_->current_token());
+      ReportUnexpectedToken(scanner()->current_token());
     } else if (!scope_->is_classic_mode()) {
-      CheckOctalLiteral(start_position, scanner_->location().end_pos, &ok);
+ CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok);
     }
     return kPreParseSuccess;
   }
@@ -604,27 +682,6 @@
   // Log the currently parsed string literal.
   Expression GetStringSymbol();

-  i::Token::Value peek() {
-    if (stack_overflow_) return i::Token::ILLEGAL;
-    return scanner_->peek();
-  }
-
-  i::Token::Value Next() {
-    if (stack_overflow_) return i::Token::ILLEGAL;
-    {
-      int marker;
-      if (reinterpret_cast<uintptr_t>(&marker) < stack_limit_) {
-        // Further calls to peek/Next will return illegal token.
-        // The current one will still be returned. It might already
-        // have been seen using peek.
-        stack_overflow_ = true;
-      }
-    }
-    return scanner_->Next();
-  }
-
-  bool peek_any_identifier();
-
   void set_language_mode(i::LanguageMode language_mode) {
     scope_->set_language_mode(language_mode);
   }
@@ -638,24 +695,6 @@
   }

   i::LanguageMode language_mode() { return scope_->language_mode(); }
-
-  void Consume(i::Token::Value token) { Next(); }
-
-  void Expect(i::Token::Value token, bool* ok) {
-    if (Next() != token) {
-      *ok = false;
-    }
-  }
-
-  bool Check(i::Token::Value token) {
-    i::Token::Value next = peek();
-    if (next == token) {
-      Consume(next);
-      return true;
-    }
-    return false;
-  }
-  void ExpectSemicolon(bool* ok);

   bool CheckInOrOf(bool accept_OF);

@@ -672,17 +711,10 @@
                                      Identifier identifier,
                                      bool* ok);

-  i::Scanner* scanner_;
   i::ParserRecorder* log_;
   Scope* scope_;
-  uintptr_t stack_limit_;
   i::Scanner::Location strict_mode_violation_location_;
   const char* strict_mode_violation_type_;
-  bool stack_overflow_;
-  bool allow_lazy_;
-  bool allow_natives_syntax_;
-  bool allow_generators_;
-  bool allow_for_of_;
   bool parenthesized_function_;

   friend class i::ObjectLiteralChecker<PreParser>;

--
--
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