Upgrade to 3.29

Update V8 to 3.29.88.17 and update makefiles to support building on
all the relevant platforms.

Bug: 17370214

Change-Id: Ia3407c157fd8d72a93e23d8318ccaf6ecf77fa4e
diff --git a/src/preparser.cc b/src/preparser.cc
index 20d3b9c..3173cc0 100644
--- a/src/preparser.cc
+++ b/src/preparser.cc
@@ -1,79 +1,147 @@
 // Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
 
-#include <math.h>
+#include <cmath>
 
-#include "../include/v8stdint.h"
+#include "include/v8stdint.h"
 
-#include "allocation.h"
-#include "checks.h"
-#include "conversions.h"
-#include "conversions-inl.h"
-#include "globals.h"
-#include "hashmap.h"
-#include "list.h"
-#include "preparse-data-format.h"
-#include "preparse-data.h"
-#include "preparser.h"
-#include "unicode.h"
-#include "utils.h"
+#include "src/allocation.h"
+#include "src/base/logging.h"
+#include "src/conversions-inl.h"
+#include "src/conversions.h"
+#include "src/globals.h"
+#include "src/hashmap.h"
+#include "src/list.h"
+#include "src/preparse-data.h"
+#include "src/preparse-data-format.h"
+#include "src/preparser.h"
+#include "src/unicode.h"
+#include "src/utils.h"
 
-namespace v8 {
+#if V8_LIBC_MSVCRT && (_MSC_VER < 1800)
+namespace std {
 
-#ifdef _MSC_VER
-// Usually defined in math.h, but not in MSVC.
+// Usually defined in math.h, but not in MSVC until VS2013+.
 // Abstracted to work
 int isfinite(double value);
+
+}  // namespace std
 #endif
 
-namespace preparser {
+namespace v8 {
+namespace internal {
+
+class PreParserTraits::Checkpoint
+    : public ParserBase<PreParserTraits>::CheckpointBase {
+ public:
+  explicit Checkpoint(ParserBase<PreParserTraits>* parser)
+      : ParserBase<PreParserTraits>::CheckpointBase(parser) {}
+};
+
+void PreParserTraits::ReportMessageAt(Scanner::Location location,
+                                      const char* message,
+                                      const char* arg,
+                                      bool is_reference_error) {
+  ReportMessageAt(location.beg_pos,
+                  location.end_pos,
+                  message,
+                  arg,
+                  is_reference_error);
+}
+
+
+void PreParserTraits::ReportMessageAt(int start_pos,
+                                      int end_pos,
+                                      const char* message,
+                                      const char* arg,
+                                      bool is_reference_error) {
+  pre_parser_->log_->LogMessage(start_pos, end_pos, message, arg,
+                                is_reference_error);
+}
+
+
+PreParserIdentifier PreParserTraits::GetSymbol(Scanner* scanner) {
+  if (scanner->current_token() == Token::FUTURE_RESERVED_WORD) {
+    return PreParserIdentifier::FutureReserved();
+  } else if (scanner->current_token() ==
+             Token::FUTURE_STRICT_RESERVED_WORD) {
+    return PreParserIdentifier::FutureStrictReserved();
+  } else if (scanner->current_token() == Token::LET) {
+    return PreParserIdentifier::Let();
+  } else if (scanner->current_token() == Token::YIELD) {
+    return PreParserIdentifier::Yield();
+  }
+  if (scanner->UnescapedLiteralMatches("eval", 4)) {
+    return PreParserIdentifier::Eval();
+  }
+  if (scanner->UnescapedLiteralMatches("arguments", 9)) {
+    return PreParserIdentifier::Arguments();
+  }
+  if (scanner->UnescapedLiteralMatches("prototype", 9)) {
+    return PreParserIdentifier::Prototype();
+  }
+  if (scanner->UnescapedLiteralMatches("constructor", 11)) {
+    return PreParserIdentifier::Constructor();
+  }
+  return PreParserIdentifier::Default();
+}
+
+
+PreParserIdentifier PreParserTraits::GetNumberAsSymbol(Scanner* scanner) {
+  return PreParserIdentifier::Default();
+}
+
+
+PreParserExpression PreParserTraits::ExpressionFromString(
+    int pos, Scanner* scanner, PreParserFactory* factory) {
+  if (scanner->UnescapedLiteralMatches("use strict", 10)) {
+    return PreParserExpression::UseStrictStringLiteral();
+  }
+  return PreParserExpression::StringLiteral();
+}
+
+
+PreParserExpression PreParserTraits::ParseV8Intrinsic(bool* ok) {
+  return pre_parser_->ParseV8Intrinsic(ok);
+}
+
+
+PreParserExpression PreParserTraits::ParseFunctionLiteral(
+    PreParserIdentifier name, Scanner::Location function_name_location,
+    bool name_is_strict_reserved, FunctionKind kind,
+    int function_token_position, FunctionLiteral::FunctionType type,
+    FunctionLiteral::ArityRestriction arity_restriction, bool* ok) {
+  return pre_parser_->ParseFunctionLiteral(
+      name, function_name_location, name_is_strict_reserved, kind,
+      function_token_position, type, arity_restriction, ok);
+}
+
 
 PreParser::PreParseResult PreParser::PreParseLazyFunction(
-    i::LanguageMode mode, i::ParserRecorder* log) {
+    StrictMode strict_mode, bool is_generator, ParserRecorder* log) {
   log_ = log;
   // Lazy functions always have trivial outer scopes (no with/catch scopes).
-  Scope top_scope(&scope_, kTopLevelScope);
-  set_language_mode(mode);
-  Scope function_scope(&scope_, kFunctionScope);
-  ASSERT_EQ(i::Token::LBRACE, scanner_->current_token());
+  PreParserScope top_scope(scope_, GLOBAL_SCOPE);
+  FunctionState top_state(&function_state_, &scope_, &top_scope, NULL,
+                          this->ast_value_factory());
+  scope_->SetStrictMode(strict_mode);
+  PreParserScope function_scope(scope_, FUNCTION_SCOPE);
+  FunctionState function_state(&function_state_, &scope_, &function_scope, NULL,
+                               this->ast_value_factory());
+  function_state.set_is_generator(is_generator);
+  DCHECK_EQ(Token::LBRACE, scanner()->current_token());
   bool ok = true;
-  int start_position = scanner_->peek_location().beg_pos;
+  int start_position = peek_position();
   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());
-    if (!is_classic_mode()) {
-      int end_pos = scanner_->location().end_pos;
+    DCHECK_EQ(Token::RBRACE, scanner()->peek());
+    if (scope_->strict_mode() == STRICT) {
+      int end_pos = scanner()->location().end_pos;
       CheckOctalLiteral(start_position, end_pos, &ok);
-      if (ok) {
-        CheckDelayedStrictModeViolation(start_position, end_pos, &ok);
-      }
     }
   }
   return kPreParseSuccess;
@@ -93,49 +161,6 @@
 // That means that contextual checks (like a label being declared where
 // it is used) are generally omitted.
 
-void PreParser::ReportUnexpectedToken(i::Token::Value token) {
-  // 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_) {
-    return;
-  }
-  i::Scanner::Location source_location = scanner_->location();
-
-  // Four of the tokens are treated specially
-  switch (token) {
-  case i::Token::EOS:
-    return ReportMessageAt(source_location, "unexpected_eos", NULL);
-  case i::Token::NUMBER:
-    return ReportMessageAt(source_location, "unexpected_token_number", NULL);
-  case i::Token::STRING:
-    return ReportMessageAt(source_location, "unexpected_token_string", NULL);
-  case i::Token::IDENTIFIER:
-    return ReportMessageAt(source_location,
-                           "unexpected_token_identifier", NULL);
-  case i::Token::FUTURE_RESERVED_WORD:
-    return ReportMessageAt(source_location, "unexpected_reserved", NULL);
-  case i::Token::FUTURE_STRICT_RESERVED_WORD:
-    return ReportMessageAt(source_location,
-                           "unexpected_strict_reserved", NULL);
-  default:
-    const char* name = i::Token::String(token);
-    ReportMessageAt(source_location, "unexpected_token", name);
-  }
-}
-
-
-// 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();
-  if (beg_pos <= octal.beg_pos && octal.end_pos <= end_pos) {
-    ReportMessageAt(octal, "strict_octal_literal", NULL);
-    scanner_->clear_octal_position();
-    *ok = false;
-  }
-}
-
 
 #define CHECK_OK  ok);                      \
   if (!*ok) return kUnknownSourceElements;  \
@@ -154,13 +179,21 @@
   // SourceElement:
   //    LetDeclaration
   //    ConstDeclaration
+  //    GeneratorDeclaration
 
   switch (peek()) {
-    case i::Token::FUNCTION:
+    case Token::FUNCTION:
       return ParseFunctionDeclaration(ok);
-    case i::Token::LET:
-    case i::Token::CONST:
+    case Token::CLASS:
+      return ParseClassDeclaration(ok);
+    case Token::CONST:
       return ParseVariableStatement(kSourceElement, ok);
+    case Token::LET:
+      DCHECK(allow_harmony_scoping());
+      if (strict_mode() == STRICT) {
+        return ParseVariableStatement(kSourceElement, ok);
+      }
+      // Fall through.
     default:
       return ParseStatement(ok);
   }
@@ -172,15 +205,17 @@
   // 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(harmony_scoping_ ?
-                          i::EXTENDED_MODE : i::STRICT_MODE);
+        scope_->SetStrictMode(STRICT);
       } else if (!statement.IsStringLiteral()) {
-        allow_directive_prologue = false;
+        directive_prologue = false;
       }
     }
   }
@@ -223,58 +258,54 @@
 
   // Keep the source position of the statement
   switch (peek()) {
-    case i::Token::LBRACE:
+    case Token::LBRACE:
       return ParseBlock(ok);
 
-    case i::Token::CONST:
-    case i::Token::LET:
-    case i::Token::VAR:
-      return ParseVariableStatement(kStatement, ok);
-
-    case i::Token::SEMICOLON:
+    case Token::SEMICOLON:
       Next();
       return Statement::Default();
 
-    case i::Token::IF:
+    case Token::IF:
       return ParseIfStatement(ok);
 
-    case i::Token::DO:
+    case Token::DO:
       return ParseDoWhileStatement(ok);
 
-    case i::Token::WHILE:
+    case Token::WHILE:
       return ParseWhileStatement(ok);
 
-    case i::Token::FOR:
+    case Token::FOR:
       return ParseForStatement(ok);
 
-    case i::Token::CONTINUE:
+    case Token::CONTINUE:
       return ParseContinueStatement(ok);
 
-    case i::Token::BREAK:
+    case Token::BREAK:
       return ParseBreakStatement(ok);
 
-    case i::Token::RETURN:
+    case Token::RETURN:
       return ParseReturnStatement(ok);
 
-    case i::Token::WITH:
+    case Token::WITH:
       return ParseWithStatement(ok);
 
-    case i::Token::SWITCH:
+    case Token::SWITCH:
       return ParseSwitchStatement(ok);
 
-    case i::Token::THROW:
+    case Token::THROW:
       return ParseThrowStatement(ok);
 
-    case i::Token::TRY:
+    case Token::TRY:
       return ParseTryStatement(ok);
 
-    case i::Token::FUNCTION: {
-      i::Scanner::Location start_location = scanner_->peek_location();
+    case Token::FUNCTION: {
+      Scanner::Location start_location = scanner()->peek_location();
       Statement statement = ParseFunctionDeclaration(CHECK_OK);
-      i::Scanner::Location end_location = scanner_->location();
-      if (!is_classic_mode()) {
-        ReportMessageAt(start_location.beg_pos, end_location.end_pos,
-                        "strict_function", NULL);
+      Scanner::Location end_location = scanner()->location();
+      if (strict_mode() == STRICT) {
+        PreParserTraits::ReportMessageAt(start_location.beg_pos,
+                                         end_location.end_pos,
+                                         "strict_function");
         *ok = false;
         return Statement::Default();
       } else {
@@ -282,9 +313,22 @@
       }
     }
 
-    case i::Token::DEBUGGER:
+    case Token::CLASS:
+      return ParseClassDeclaration(CHECK_OK);
+
+    case Token::DEBUGGER:
       return ParseDebuggerStatement(ok);
 
+    case Token::VAR:
+    case Token::CONST:
+      return ParseVariableStatement(kStatement, ok);
+
+    case Token::LET:
+      DCHECK(allow_harmony_scoping());
+      if (strict_mode() == STRICT) {
+        return ParseVariableStatement(kStatement, ok);
+      }
+      // Fall through.
     default:
       return ParseExpressionOrLabelledStatement(ok);
   }
@@ -294,28 +338,36 @@
 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
   // FunctionDeclaration ::
   //   'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
-  Expect(i::Token::FUNCTION, CHECK_OK);
-
-  Identifier identifier = ParseIdentifier(CHECK_OK);
-  i::Scanner::Location location = scanner_->location();
-
-  Expression function_value = ParseFunctionLiteral(CHECK_OK);
-
-  if (function_value.IsStrictFunction() &&
-      !identifier.IsValidStrictVariable()) {
-    // Strict mode violation, using either reserved word or eval/arguments
-    // as name of strict function.
-    const char* type = "strict_function_name";
-    if (identifier.IsFutureStrictReserved()) {
-      type = "strict_reserved_word";
-    }
-    ReportMessageAt(location, type, NULL);
-    *ok = false;
-  }
+  // GeneratorDeclaration ::
+  //   'function' '*' Identifier '(' FormalParameterListopt ')'
+  //      '{' FunctionBody '}'
+  Expect(Token::FUNCTION, CHECK_OK);
+  int pos = position();
+  bool is_generator = Check(Token::MUL);
+  bool is_strict_reserved = false;
+  Identifier name = ParseIdentifierOrStrictReservedWord(
+      &is_strict_reserved, CHECK_OK);
+  ParseFunctionLiteral(name, scanner()->location(), is_strict_reserved,
+                       is_generator ? FunctionKind::kGeneratorFunction
+                                    : FunctionKind::kNormalFunction,
+                       pos, FunctionLiteral::DECLARATION,
+                       FunctionLiteral::NORMAL_ARITY, CHECK_OK);
   return Statement::FunctionDeclaration();
 }
 
 
+PreParser::Statement PreParser::ParseClassDeclaration(bool* ok) {
+  Expect(Token::CLASS, CHECK_OK);
+  int pos = position();
+  bool is_strict_reserved = false;
+  Identifier name =
+      ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
+  ParseClassLiteral(name, scanner()->location(), is_strict_reserved, pos,
+                    CHECK_OK);
+  return Statement::Default();
+}
+
+
 PreParser::Statement PreParser::ParseBlock(bool* ok) {
   // Block ::
   //   '{' Statement* '}'
@@ -323,15 +375,15 @@
   // Note that a Block does not introduce a new execution scope!
   // (ECMA-262, 3rd, 12.2)
   //
-  Expect(i::Token::LBRACE, CHECK_OK);
-  while (peek() != i::Token::RBRACE) {
-    if (is_extended_mode()) {
+  Expect(Token::LBRACE, CHECK_OK);
+  while (peek() != Token::RBRACE) {
+    if (allow_harmony_scoping() && strict_mode() == STRICT) {
       ParseSourceElement(CHECK_OK);
     } else {
       ParseStatement(CHECK_OK);
     }
   }
-  Expect(i::Token::RBRACE, ok);
+  Expect(Token::RBRACE, ok);
   return Statement::Default();
 }
 
@@ -375,9 +427,9 @@
   // ConstBinding ::
   //   BindingPattern '=' AssignmentExpression
   bool require_initializer = false;
-  if (peek() == i::Token::VAR) {
-    Consume(i::Token::VAR);
-  } else if (peek() == i::Token::CONST) {
+  if (peek() == Token::VAR) {
+    Consume(Token::VAR);
+  } else if (peek() == Token::CONST) {
     // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads:
     //
     // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
@@ -385,51 +437,29 @@
     // * It is a Syntax Error if the code that matches this production is not
     //   contained in extended code.
     //
-    // However disallowing const in classic mode will break compatibility with
+    // However disallowing const in sloppy mode will break compatibility with
     // existing pages. Therefore we keep allowing const with the old
-    // non-harmony semantics in classic mode.
-    Consume(i::Token::CONST);
-    switch (language_mode()) {
-      case i::CLASSIC_MODE:
-        break;
-      case i::STRICT_MODE: {
-        i::Scanner::Location location = scanner_->peek_location();
-        ReportMessageAt(location, "strict_const", NULL);
-        *ok = false;
-        return Statement::Default();
-      }
-      case i::EXTENDED_MODE:
-        if (var_context != kSourceElement &&
-            var_context != kForStatement) {
-          i::Scanner::Location location = scanner_->peek_location();
-          ReportMessageAt(location.beg_pos, location.end_pos,
-                          "unprotected_const", NULL);
+    // non-harmony semantics in sloppy mode.
+    Consume(Token::CONST);
+    if (strict_mode() == STRICT) {
+      if (allow_harmony_scoping()) {
+        if (var_context != kSourceElement && var_context != kForStatement) {
+          ReportMessageAt(scanner()->peek_location(), "unprotected_const");
           *ok = false;
           return Statement::Default();
         }
         require_initializer = true;
-        break;
+      } else {
+        Scanner::Location location = scanner()->peek_location();
+        ReportMessageAt(location, "strict_const");
+        *ok = false;
+        return Statement::Default();
+      }
     }
-  } else if (peek() == i::Token::LET) {
-    // ES6 Draft Rev4 section 12.2.1:
-    //
-    // LetDeclaration : let LetBindingList ;
-    //
-    // * 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();
-      ReportMessageAt(location.beg_pos, location.end_pos,
-                      "illegal_let", NULL);
-      *ok = false;
-      return Statement::Default();
-    }
-    Consume(i::Token::LET);
-    if (var_context != kSourceElement &&
-        var_context != kForStatement) {
-      i::Scanner::Location location = scanner_->peek_location();
-      ReportMessageAt(location.beg_pos, location.end_pos,
-                      "unprotected_let", NULL);
+  } else if (peek() == Token::LET && strict_mode() == STRICT) {
+    Consume(Token::LET);
+    if (var_context != kSourceElement && var_context != kForStatement) {
+      ReportMessageAt(scanner()->peek_location(), "unprotected_let");
       *ok = false;
       return Statement::Default();
     }
@@ -445,22 +475,15 @@
   int nvars = 0;  // the number of variables declared
   do {
     // Parse variable name.
-    if (nvars > 0) Consume(i::Token::COMMA);
-    Identifier identifier  = ParseIdentifier(CHECK_OK);
-    if (!is_classic_mode() && !identifier.IsValidStrictVariable()) {
-      StrictModeIdentifierViolation(scanner_->location(),
-                                    "strict_var_name",
-                                    identifier,
-                                    ok);
-      return Statement::Default();
-    }
+    if (nvars > 0) Consume(Token::COMMA);
+    ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
     nvars++;
-    if (peek() == i::Token::ASSIGN || require_initializer) {
-      Expect(i::Token::ASSIGN, CHECK_OK);
+    if (peek() == Token::ASSIGN || require_initializer) {
+      Expect(Token::ASSIGN, CHECK_OK);
       ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
       if (decl_props != NULL) *decl_props = kHasInitializers;
     }
-  } while (peek() == i::Token::COMMA);
+  } while (peek() == Token::COMMA);
 
   if (num_decl != NULL) *num_decl = nvars;
   return Statement::Default();
@@ -472,14 +495,20 @@
   //   Expression ';'
   //   Identifier ':' Statement
 
+  bool starts_with_identifier = peek_any_identifier();
   Expression expr = ParseExpression(true, CHECK_OK);
-  if (expr.IsRawIdentifier()) {
-    ASSERT(!expr.AsIdentifier().IsFutureReserved());
-    ASSERT(is_classic_mode() || !expr.AsIdentifier().IsFutureStrictReserved());
-    if (peek() == i::Token::COLON) {
-      Consume(i::Token::COLON);
-      return ParseStatement(ok);
-    }
+  // 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.
+    DCHECK(!expr.AsIdentifier().IsFutureReserved());
+    DCHECK(strict_mode() == SLOPPY ||
+           (!expr.AsIdentifier().IsFutureStrictReserved() &&
+            !expr.AsIdentifier().IsYield()));
+    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.
@@ -494,12 +523,12 @@
   // IfStatement ::
   //   'if' '(' Expression ')' Statement ('else' Statement)?
 
-  Expect(i::Token::IF, CHECK_OK);
-  Expect(i::Token::LPAREN, CHECK_OK);
+  Expect(Token::IF, CHECK_OK);
+  Expect(Token::LPAREN, CHECK_OK);
   ParseExpression(true, CHECK_OK);
-  Expect(i::Token::RPAREN, CHECK_OK);
+  Expect(Token::RPAREN, CHECK_OK);
   ParseStatement(CHECK_OK);
-  if (peek() == i::Token::ELSE) {
+  if (peek() == Token::ELSE) {
     Next();
     ParseStatement(CHECK_OK);
   }
@@ -511,13 +540,14 @@
   // ContinueStatement ::
   //   'continue' [no line terminator] Identifier? ';'
 
-  Expect(i::Token::CONTINUE, CHECK_OK);
-  i::Token::Value tok = peek();
-  if (!scanner_->HasAnyLineTerminatorBeforeNext() &&
-      tok != i::Token::SEMICOLON &&
-      tok != i::Token::RBRACE &&
-      tok != i::Token::EOS) {
-    ParseIdentifier(CHECK_OK);
+  Expect(Token::CONTINUE, CHECK_OK);
+  Token::Value tok = peek();
+  if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
+      tok != Token::SEMICOLON &&
+      tok != Token::RBRACE &&
+      tok != Token::EOS) {
+    // ECMA allows "eval" or "arguments" as labels even in strict mode.
+    ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
   }
   ExpectSemicolon(CHECK_OK);
   return Statement::Default();
@@ -528,13 +558,14 @@
   // BreakStatement ::
   //   'break' [no line terminator] Identifier? ';'
 
-  Expect(i::Token::BREAK, CHECK_OK);
-  i::Token::Value tok = peek();
-  if (!scanner_->HasAnyLineTerminatorBeforeNext() &&
-      tok != i::Token::SEMICOLON &&
-      tok != i::Token::RBRACE &&
-      tok != i::Token::EOS) {
-    ParseIdentifier(CHECK_OK);
+  Expect(Token::BREAK, CHECK_OK);
+  Token::Value tok = peek();
+  if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
+      tok != Token::SEMICOLON &&
+      tok != Token::RBRACE &&
+      tok != Token::EOS) {
+    // ECMA allows "eval" or "arguments" as labels even in strict mode.
+    ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
   }
   ExpectSemicolon(CHECK_OK);
   return Statement::Default();
@@ -545,21 +576,21 @@
   // ReturnStatement ::
   //   'return' [no line terminator] Expression? ';'
 
-  // Consume the return token. It is necessary to do the before
+  // Consume the return token. It is necessary to do before
   // reporting any errors on it, because of the way errors are
   // reported (underlining).
-  Expect(i::Token::RETURN, CHECK_OK);
+  Expect(Token::RETURN, CHECK_OK);
 
   // An ECMAScript program is considered syntactically incorrect if it
   // contains a return statement that is not within the body of a
   // function. See ECMA-262, section 12.9, page 67.
   // This is not handled during preparsing.
 
-  i::Token::Value tok = peek();
-  if (!scanner_->HasAnyLineTerminatorBeforeNext() &&
-      tok != i::Token::SEMICOLON &&
-      tok != i::Token::RBRACE &&
-      tok != i::Token::EOS) {
+  Token::Value tok = peek();
+  if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
+      tok != Token::SEMICOLON &&
+      tok != Token::RBRACE &&
+      tok != Token::EOS) {
     ParseExpression(true, CHECK_OK);
   }
   ExpectSemicolon(CHECK_OK);
@@ -570,20 +601,19 @@
 PreParser::Statement PreParser::ParseWithStatement(bool* ok) {
   // WithStatement ::
   //   'with' '(' Expression ')' Statement
-  Expect(i::Token::WITH, CHECK_OK);
-  if (!is_classic_mode()) {
-    i::Scanner::Location location = scanner_->location();
-    ReportMessageAt(location, "strict_mode_with", NULL);
+  Expect(Token::WITH, CHECK_OK);
+  if (strict_mode() == STRICT) {
+    ReportMessageAt(scanner()->location(), "strict_mode_with");
     *ok = false;
     return Statement::Default();
   }
-  Expect(i::Token::LPAREN, CHECK_OK);
+  Expect(Token::LPAREN, CHECK_OK);
   ParseExpression(true, CHECK_OK);
-  Expect(i::Token::RPAREN, CHECK_OK);
+  Expect(Token::RPAREN, CHECK_OK);
 
-  scope_->EnterWith();
+  PreParserScope with_scope(scope_, WITH_SCOPE);
+  BlockState block_state(&scope_, &with_scope);
   ParseStatement(CHECK_OK);
-  scope_->LeaveWith();
   return Statement::Default();
 }
 
@@ -592,27 +622,30 @@
   // SwitchStatement ::
   //   'switch' '(' Expression ')' '{' CaseClause* '}'
 
-  Expect(i::Token::SWITCH, CHECK_OK);
-  Expect(i::Token::LPAREN, CHECK_OK);
+  Expect(Token::SWITCH, CHECK_OK);
+  Expect(Token::LPAREN, CHECK_OK);
   ParseExpression(true, CHECK_OK);
-  Expect(i::Token::RPAREN, CHECK_OK);
+  Expect(Token::RPAREN, CHECK_OK);
 
-  Expect(i::Token::LBRACE, CHECK_OK);
-  i::Token::Value token = peek();
-  while (token != i::Token::RBRACE) {
-    if (token == i::Token::CASE) {
-      Expect(i::Token::CASE, CHECK_OK);
+  Expect(Token::LBRACE, CHECK_OK);
+  Token::Value token = peek();
+  while (token != Token::RBRACE) {
+    if (token == Token::CASE) {
+      Expect(Token::CASE, CHECK_OK);
       ParseExpression(true, CHECK_OK);
-      Expect(i::Token::COLON, CHECK_OK);
-    } else if (token == i::Token::DEFAULT) {
-      Expect(i::Token::DEFAULT, CHECK_OK);
-      Expect(i::Token::COLON, CHECK_OK);
     } else {
-      ParseStatement(CHECK_OK);
+      Expect(Token::DEFAULT, CHECK_OK);
     }
+    Expect(Token::COLON, CHECK_OK);
     token = peek();
+    while (token != Token::CASE &&
+           token != Token::DEFAULT &&
+           token != Token::RBRACE) {
+      ParseStatement(CHECK_OK);
+      token = peek();
+    }
   }
-  Expect(i::Token::RBRACE, ok);
+  Expect(Token::RBRACE, ok);
   return Statement::Default();
 }
 
@@ -621,13 +654,13 @@
   // DoStatement ::
   //   'do' Statement 'while' '(' Expression ')' ';'
 
-  Expect(i::Token::DO, CHECK_OK);
+  Expect(Token::DO, CHECK_OK);
   ParseStatement(CHECK_OK);
-  Expect(i::Token::WHILE, CHECK_OK);
-  Expect(i::Token::LPAREN, CHECK_OK);
+  Expect(Token::WHILE, CHECK_OK);
+  Expect(Token::LPAREN, CHECK_OK);
   ParseExpression(true, CHECK_OK);
-  Expect(i::Token::RPAREN, ok);
-  if (peek() == i::Token::SEMICOLON) Consume(i::Token::SEMICOLON);
+  Expect(Token::RPAREN, ok);
+  if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
   return Statement::Default();
 }
 
@@ -636,45 +669,53 @@
   // WhileStatement ::
   //   'while' '(' Expression ')' Statement
 
-  Expect(i::Token::WHILE, CHECK_OK);
-  Expect(i::Token::LPAREN, CHECK_OK);
+  Expect(Token::WHILE, CHECK_OK);
+  Expect(Token::LPAREN, CHECK_OK);
   ParseExpression(true, CHECK_OK);
-  Expect(i::Token::RPAREN, CHECK_OK);
+  Expect(Token::RPAREN, CHECK_OK);
   ParseStatement(ok);
   return Statement::Default();
 }
 
 
+bool PreParser::CheckInOrOf(bool accept_OF) {
+  if (Check(Token::IN) ||
+      (accept_OF && CheckContextualKeyword(CStrVector("of")))) {
+    return true;
+  }
+  return false;
+}
+
+
 PreParser::Statement PreParser::ParseForStatement(bool* ok) {
   // ForStatement ::
   //   'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
 
-  Expect(i::Token::FOR, CHECK_OK);
-  Expect(i::Token::LPAREN, CHECK_OK);
-  if (peek() != i::Token::SEMICOLON) {
-    if (peek() == i::Token::VAR || peek() == i::Token::CONST ||
-        peek() == i::Token::LET) {
-      bool is_let = peek() == i::Token::LET;
+  Expect(Token::FOR, CHECK_OK);
+  Expect(Token::LPAREN, CHECK_OK);
+  if (peek() != Token::SEMICOLON) {
+    if (peek() == Token::VAR || peek() == Token::CONST ||
+        (peek() == Token::LET && strict_mode() == STRICT)) {
+      bool is_let = peek() == Token::LET;
       int decl_count;
       VariableDeclarationProperties decl_props = kHasNoInitializers;
       ParseVariableDeclarations(
           kForStatement, &decl_props, &decl_count, CHECK_OK);
-      bool accept_IN = decl_count == 1 &&
-          !(is_let && decl_props == kHasInitializers);
-      if (peek() == i::Token::IN && accept_IN) {
-        Expect(i::Token::IN, CHECK_OK);
+      bool has_initializers = decl_props == kHasInitializers;
+      bool accept_IN = decl_count == 1 && !(is_let && has_initializers);
+      bool accept_OF = !has_initializers;
+      if (accept_IN && CheckInOrOf(accept_OF)) {
         ParseExpression(true, CHECK_OK);
-        Expect(i::Token::RPAREN, CHECK_OK);
+        Expect(Token::RPAREN, CHECK_OK);
 
         ParseStatement(CHECK_OK);
         return Statement::Default();
       }
     } else {
-      ParseExpression(false, CHECK_OK);
-      if (peek() == i::Token::IN) {
-        Expect(i::Token::IN, CHECK_OK);
+      Expression lhs = ParseExpression(false, CHECK_OK);
+      if (CheckInOrOf(lhs.IsIdentifier())) {
         ParseExpression(true, CHECK_OK);
-        Expect(i::Token::RPAREN, CHECK_OK);
+        Expect(Token::RPAREN, CHECK_OK);
 
         ParseStatement(CHECK_OK);
         return Statement::Default();
@@ -683,17 +724,17 @@
   }
 
   // Parsed initializer at this point.
-  Expect(i::Token::SEMICOLON, CHECK_OK);
+  Expect(Token::SEMICOLON, CHECK_OK);
 
-  if (peek() != i::Token::SEMICOLON) {
+  if (peek() != Token::SEMICOLON) {
     ParseExpression(true, CHECK_OK);
   }
-  Expect(i::Token::SEMICOLON, CHECK_OK);
+  Expect(Token::SEMICOLON, CHECK_OK);
 
-  if (peek() != i::Token::RPAREN) {
+  if (peek() != Token::RPAREN) {
     ParseExpression(true, CHECK_OK);
   }
-  Expect(i::Token::RPAREN, CHECK_OK);
+  Expect(Token::RPAREN, CHECK_OK);
 
   ParseStatement(ok);
   return Statement::Default();
@@ -704,10 +745,9 @@
   // ThrowStatement ::
   //   'throw' [no line terminator] Expression ';'
 
-  Expect(i::Token::THROW, CHECK_OK);
-  if (scanner_->HasAnyLineTerminatorBeforeNext()) {
-    i::Scanner::Location pos = scanner_->location();
-    ReportMessageAt(pos, "newline_after_throw", NULL);
+  Expect(Token::THROW, CHECK_OK);
+  if (scanner()->HasAnyLineTerminatorBeforeNext()) {
+    ReportMessageAt(scanner()->location(), "newline_after_throw");
     *ok = false;
     return Statement::Default();
   }
@@ -729,39 +769,31 @@
   // Finally ::
   //   'finally' Block
 
-  // In preparsing, allow any number of catch/finally blocks, including zero
-  // of both.
-
-  Expect(i::Token::TRY, CHECK_OK);
+  Expect(Token::TRY, CHECK_OK);
 
   ParseBlock(CHECK_OK);
 
-  bool catch_or_finally_seen = false;
-  if (peek() == i::Token::CATCH) {
-    Consume(i::Token::CATCH);
-    Expect(i::Token::LPAREN, CHECK_OK);
-    Identifier id = ParseIdentifier(CHECK_OK);
-    if (!is_classic_mode() && !id.IsValidStrictVariable()) {
-      StrictModeIdentifierViolation(scanner_->location(),
-                                    "strict_catch_variable",
-                                    id,
-                                    ok);
-      return Statement::Default();
-    }
-    Expect(i::Token::RPAREN, CHECK_OK);
-    scope_->EnterWith();
-    ParseBlock(ok);
-    scope_->LeaveWith();
-    if (!*ok) Statement::Default();
-    catch_or_finally_seen = true;
-  }
-  if (peek() == i::Token::FINALLY) {
-    Consume(i::Token::FINALLY);
-    ParseBlock(CHECK_OK);
-    catch_or_finally_seen = true;
-  }
-  if (!catch_or_finally_seen) {
+  Token::Value tok = peek();
+  if (tok != Token::CATCH && tok != Token::FINALLY) {
+    ReportMessageAt(scanner()->location(), "no_catch_or_finally");
     *ok = false;
+    return Statement::Default();
+  }
+  if (tok == Token::CATCH) {
+    Consume(Token::CATCH);
+    Expect(Token::LPAREN, CHECK_OK);
+    ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
+    Expect(Token::RPAREN, CHECK_OK);
+    {
+      PreParserScope with_scope(scope_, WITH_SCOPE);
+      BlockState block_state(&scope_, &with_scope);
+      ParseBlock(CHECK_OK);
+    }
+    tok = peek();
+  }
+  if (tok == Token::FINALLY) {
+    Consume(Token::FINALLY);
+    ParseBlock(CHECK_OK);
   }
   return Statement::Default();
 }
@@ -774,7 +806,7 @@
   // DebuggerStatement ::
   //   'debugger' ';'
 
-  Expect(i::Token::DEBUGGER, CHECK_OK);
+  Expect(Token::DEBUGGER, CHECK_OK);
   ExpectSemicolon(ok);
   return Statement::Default();
 }
@@ -788,641 +820,104 @@
 #undef DUMMY
 
 
-// Precedence = 1
-PreParser::Expression PreParser::ParseExpression(bool accept_IN, bool* ok) {
-  // Expression ::
-  //   AssignmentExpression
-  //   Expression ',' AssignmentExpression
-
-  Expression result = ParseAssignmentExpression(accept_IN, CHECK_OK);
-  while (peek() == i::Token::COMMA) {
-    Expect(i::Token::COMMA, CHECK_OK);
-    ParseAssignmentExpression(accept_IN, CHECK_OK);
-    result = Expression::Default();
-  }
-  return result;
-}
-
-
-// Precedence = 2
-PreParser::Expression PreParser::ParseAssignmentExpression(bool accept_IN,
-                                                           bool* ok) {
-  // AssignmentExpression ::
-  //   ConditionalExpression
-  //   LeftHandSideExpression AssignmentOperator AssignmentExpression
-
-  i::Scanner::Location before = scanner_->peek_location();
-  Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK);
-
-  if (!i::Token::IsAssignmentOp(peek())) {
-    // Parsed conditional expression only (no assignment).
-    return expression;
-  }
-
-  if (!is_classic_mode() &&
-      expression.IsIdentifier() &&
-      expression.AsIdentifier().IsEvalOrArguments()) {
-    i::Scanner::Location after = scanner_->location();
-    ReportMessageAt(before.beg_pos, after.end_pos,
-                    "strict_lhs_assignment", NULL);
-    *ok = false;
-    return Expression::Default();
-  }
-
-  i::Token::Value op = Next();  // Get assignment operator.
-  ParseAssignmentExpression(accept_IN, CHECK_OK);
-
-  if ((op == i::Token::ASSIGN) && expression.IsThisProperty()) {
-    scope_->AddProperty();
-  }
-
-  return Expression::Default();
-}
-
-
-// Precedence = 3
-PreParser::Expression PreParser::ParseConditionalExpression(bool accept_IN,
-                                                            bool* ok) {
-  // ConditionalExpression ::
-  //   LogicalOrExpression
-  //   LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
-
-  // We start using the binary expression parser for prec >= 4 only!
-  Expression expression = ParseBinaryExpression(4, accept_IN, CHECK_OK);
-  if (peek() != i::Token::CONDITIONAL) return expression;
-  Consume(i::Token::CONDITIONAL);
-  // In parsing the first assignment expression in conditional
-  // expressions we always accept the 'in' keyword; see ECMA-262,
-  // section 11.12, page 58.
-  ParseAssignmentExpression(true, CHECK_OK);
-  Expect(i::Token::COLON, CHECK_OK);
-  ParseAssignmentExpression(accept_IN, CHECK_OK);
-  return Expression::Default();
-}
-
-
-int PreParser::Precedence(i::Token::Value tok, bool accept_IN) {
-  if (tok == i::Token::IN && !accept_IN)
-    return 0;  // 0 precedence will terminate binary expression parsing
-
-  return i::Token::Precedence(tok);
-}
-
-
-// Precedence >= 4
-PreParser::Expression PreParser::ParseBinaryExpression(int prec,
-                                                       bool accept_IN,
-                                                       bool* ok) {
-  Expression result = ParseUnaryExpression(CHECK_OK);
-  for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
-    // prec1 >= 4
-    while (Precedence(peek(), accept_IN) == prec1) {
-      Next();
-      ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK);
-      result = Expression::Default();
-    }
-  }
-  return result;
-}
-
-
-PreParser::Expression PreParser::ParseUnaryExpression(bool* ok) {
-  // UnaryExpression ::
-  //   PostfixExpression
-  //   'delete' UnaryExpression
-  //   'void' UnaryExpression
-  //   'typeof' UnaryExpression
-  //   '++' UnaryExpression
-  //   '--' UnaryExpression
-  //   '+' UnaryExpression
-  //   '-' UnaryExpression
-  //   '~' UnaryExpression
-  //   '!' UnaryExpression
-
-  i::Token::Value op = peek();
-  if (i::Token::IsUnaryOp(op)) {
-    op = Next();
-    ParseUnaryExpression(ok);
-    return Expression::Default();
-  } else if (i::Token::IsCountOp(op)) {
-    op = Next();
-    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();
-      ReportMessageAt(before.beg_pos, after.end_pos,
-                      "strict_lhs_prefix", NULL);
-      *ok = false;
-    }
-    return Expression::Default();
-  } else {
-    return ParsePostfixExpression(ok);
-  }
-}
-
-
-PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) {
-  // PostfixExpression ::
-  //   LeftHandSideExpression ('++' | '--')?
-
-  i::Scanner::Location before = scanner_->peek_location();
-  Expression expression = ParseLeftHandSideExpression(CHECK_OK);
-  if (!scanner_->HasAnyLineTerminatorBeforeNext() &&
-      i::Token::IsCountOp(peek())) {
-    if (!is_classic_mode() &&
-        expression.IsIdentifier() &&
-        expression.AsIdentifier().IsEvalOrArguments()) {
-      i::Scanner::Location after = scanner_->location();
-      ReportMessageAt(before.beg_pos, after.end_pos,
-                      "strict_lhs_postfix", NULL);
-      *ok = false;
-      return Expression::Default();
-    }
-    Next();
-    return Expression::Default();
-  }
-  return expression;
-}
-
-
-PreParser::Expression PreParser::ParseLeftHandSideExpression(bool* ok) {
-  // LeftHandSideExpression ::
-  //   (NewExpression | MemberExpression) ...
-
-  Expression result = Expression::Default();
-  if (peek() == i::Token::NEW) {
-    result = ParseNewExpression(CHECK_OK);
-  } else {
-    result = ParseMemberExpression(CHECK_OK);
-  }
-
-  while (true) {
-    switch (peek()) {
-      case i::Token::LBRACK: {
-        Consume(i::Token::LBRACK);
-        ParseExpression(true, CHECK_OK);
-        Expect(i::Token::RBRACK, CHECK_OK);
-        if (result.IsThis()) {
-          result = Expression::ThisProperty();
-        } else {
-          result = Expression::Default();
-        }
-        break;
-      }
-
-      case i::Token::LPAREN: {
-        ParseArguments(CHECK_OK);
-        result = Expression::Default();
-        break;
-      }
-
-      case i::Token::PERIOD: {
-        Consume(i::Token::PERIOD);
-        ParseIdentifierName(CHECK_OK);
-        if (result.IsThis()) {
-          result = Expression::ThisProperty();
-        } else {
-          result = Expression::Default();
-        }
-        break;
-      }
-
-      default:
-        return result;
-    }
-  }
-}
-
-
-PreParser::Expression PreParser::ParseNewExpression(bool* ok) {
-  // NewExpression ::
-  //   ('new')+ MemberExpression
-
-  // The grammar for new expressions is pretty warped. The keyword
-  // 'new' can either be a part of the new expression (where it isn't
-  // followed by an argument list) or a part of the member expression,
-  // where it must be followed by an argument list. To accommodate
-  // this, we parse the 'new' keywords greedily and keep track of how
-  // many we have parsed. This information is then passed on to the
-  // member expression parser, which is only allowed to match argument
-  // lists as long as it has 'new' prefixes left
-  unsigned new_count = 0;
-  do {
-    Consume(i::Token::NEW);
-    new_count++;
-  } while (peek() == i::Token::NEW);
-
-  return ParseMemberWithNewPrefixesExpression(new_count, ok);
-}
-
-
-PreParser::Expression PreParser::ParseMemberExpression(bool* ok) {
-  return ParseMemberWithNewPrefixesExpression(0, ok);
-}
-
-
-PreParser::Expression PreParser::ParseMemberWithNewPrefixesExpression(
-    unsigned new_count, bool* ok) {
-  // MemberExpression ::
-  //   (PrimaryExpression | FunctionLiteral)
-  //     ('[' Expression ']' | '.' Identifier | Arguments)*
-
-  // Parse the initial primary or function expression.
-  Expression result = Expression::Default();
-  if (peek() == i::Token::FUNCTION) {
-    Consume(i::Token::FUNCTION);
-    Identifier identifier = Identifier::Default();
-    if (peek_any_identifier()) {
-      identifier = ParseIdentifier(CHECK_OK);
-    }
-    result = ParseFunctionLiteral(CHECK_OK);
-    if (result.IsStrictFunction() && !identifier.IsValidStrictVariable()) {
-      StrictModeIdentifierViolation(scanner_->location(),
-                                    "strict_function_name",
-                                    identifier,
-                                    ok);
-      return Expression::Default();
-    }
-  } else {
-    result = ParsePrimaryExpression(CHECK_OK);
-  }
-
-  while (true) {
-    switch (peek()) {
-      case i::Token::LBRACK: {
-        Consume(i::Token::LBRACK);
-        ParseExpression(true, CHECK_OK);
-        Expect(i::Token::RBRACK, CHECK_OK);
-        if (result.IsThis()) {
-          result = Expression::ThisProperty();
-        } else {
-          result = Expression::Default();
-        }
-        break;
-      }
-      case i::Token::PERIOD: {
-        Consume(i::Token::PERIOD);
-        ParseIdentifierName(CHECK_OK);
-        if (result.IsThis()) {
-          result = Expression::ThisProperty();
-        } else {
-          result = Expression::Default();
-        }
-        break;
-      }
-      case i::Token::LPAREN: {
-        if (new_count == 0) return result;
-        // Consume one of the new prefixes (already parsed).
-        ParseArguments(CHECK_OK);
-        new_count--;
-        result = Expression::Default();
-        break;
-      }
-      default:
-        return result;
-    }
-  }
-}
-
-
-PreParser::Expression PreParser::ParsePrimaryExpression(bool* ok) {
-  // PrimaryExpression ::
-  //   'this'
-  //   'null'
-  //   'true'
-  //   'false'
-  //   Identifier
-  //   Number
-  //   String
-  //   ArrayLiteral
-  //   ObjectLiteral
-  //   RegExpLiteral
-  //   '(' Expression ')'
-
-  Expression result = Expression::Default();
-  switch (peek()) {
-    case i::Token::THIS: {
-      Next();
-      result = Expression::This();
-      break;
-    }
-
-    case i::Token::FUTURE_RESERVED_WORD: {
-      Next();
-      i::Scanner::Location location = scanner_->location();
-      ReportMessageAt(location.beg_pos, location.end_pos,
-                      "reserved_word", NULL);
-      *ok = false;
-      return Expression::Default();
-    }
-
-    case i::Token::FUTURE_STRICT_RESERVED_WORD:
-      if (!is_classic_mode()) {
-        Next();
-        i::Scanner::Location location = scanner_->location();
-        ReportMessageAt(location, "strict_reserved_word", NULL);
-        *ok = false;
-        return Expression::Default();
-      }
-      // FALLTHROUGH
-    case i::Token::IDENTIFIER: {
-      Identifier id = ParseIdentifier(CHECK_OK);
-      result = Expression::FromIdentifier(id);
-      break;
-    }
-
-    case i::Token::NULL_LITERAL:
-    case i::Token::TRUE_LITERAL:
-    case i::Token::FALSE_LITERAL:
-    case i::Token::NUMBER: {
-      Next();
-      break;
-    }
-    case i::Token::STRING: {
-      Next();
-      result = GetStringSymbol();
-      break;
-    }
-
-    case i::Token::ASSIGN_DIV:
-      result = ParseRegExpLiteral(true, CHECK_OK);
-      break;
-
-    case i::Token::DIV:
-      result = ParseRegExpLiteral(false, CHECK_OK);
-      break;
-
-    case i::Token::LBRACK:
-      result = ParseArrayLiteral(CHECK_OK);
-      break;
-
-    case i::Token::LBRACE:
-      result = ParseObjectLiteral(CHECK_OK);
-      break;
-
-    case i::Token::LPAREN:
-      Consume(i::Token::LPAREN);
-      parenthesized_function_ = (peek() == i::Token::FUNCTION);
-      result = ParseExpression(true, CHECK_OK);
-      Expect(i::Token::RPAREN, CHECK_OK);
-      result = result.Parenthesize();
-      break;
-
-    case i::Token::MOD:
-      result = ParseV8Intrinsic(CHECK_OK);
-      break;
-
-    default: {
-      Next();
-      *ok = false;
-      return Expression::Default();
-    }
-  }
-
-  return result;
-}
-
-
-PreParser::Expression PreParser::ParseArrayLiteral(bool* ok) {
-  // ArrayLiteral ::
-  //   '[' Expression? (',' Expression?)* ']'
-  Expect(i::Token::LBRACK, CHECK_OK);
-  while (peek() != i::Token::RBRACK) {
-    if (peek() != i::Token::COMMA) {
-      ParseAssignmentExpression(true, CHECK_OK);
-    }
-    if (peek() != i::Token::RBRACK) {
-      Expect(i::Token::COMMA, CHECK_OK);
-    }
-  }
-  Expect(i::Token::RBRACK, CHECK_OK);
-
-  scope_->NextMaterializedLiteralIndex();
-  return Expression::Default();
-}
-
-void PreParser::CheckDuplicate(DuplicateFinder* finder,
-                               i::Token::Value property,
-                               int type,
-                               bool* ok) {
-  int old_type;
-  if (property == i::Token::NUMBER) {
-    old_type = finder->AddNumber(scanner_->literal_ascii_string(), type);
-  } else if (scanner_->is_literal_ascii()) {
-    old_type = finder->AddAsciiSymbol(scanner_->literal_ascii_string(),
-                                      type);
-  } else {
-    old_type = finder->AddUtf16Symbol(scanner_->literal_utf16_string(), type);
-  }
-  if (HasConflict(old_type, type)) {
-    if (IsDataDataConflict(old_type, type)) {
-      // Both are data properties.
-      if (is_classic_mode()) return;
-      ReportMessageAt(scanner_->location(),
-                      "strict_duplicate_property", NULL);
-    } else if (IsDataAccessorConflict(old_type, type)) {
-      // Both a data and an accessor property with the same name.
-      ReportMessageAt(scanner_->location(),
-                      "accessor_data_property", NULL);
-    } else {
-      ASSERT(IsAccessorAccessorConflict(old_type, type));
-      // Both accessors of the same type.
-      ReportMessageAt(scanner_->location(),
-                      "accessor_get_set", NULL);
-    }
-    *ok = false;
-  }
-}
-
-
-PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) {
-  // ObjectLiteral ::
-  //   '{' (
-  //       ((IdentifierName | String | Number) ':' AssignmentExpression)
-  //     | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
-  //    )*[','] '}'
-
-  Expect(i::Token::LBRACE, CHECK_OK);
-  DuplicateFinder duplicate_finder(scanner_->unicode_cache());
-  while (peek() != i::Token::RBRACE) {
-    i::Token::Value next = peek();
-    switch (next) {
-      case i::Token::IDENTIFIER:
-      case i::Token::FUTURE_RESERVED_WORD:
-      case i::Token::FUTURE_STRICT_RESERVED_WORD: {
-        bool is_getter = false;
-        bool is_setter = false;
-        ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
-        if ((is_getter || is_setter) && peek() != i::Token::COLON) {
-            i::Token::Value name = Next();
-            bool is_keyword = i::Token::IsKeyword(name);
-            if (name != i::Token::IDENTIFIER &&
-                name != i::Token::FUTURE_RESERVED_WORD &&
-                name != i::Token::FUTURE_STRICT_RESERVED_WORD &&
-                name != i::Token::NUMBER &&
-                name != i::Token::STRING &&
-                !is_keyword) {
-              *ok = false;
-              return Expression::Default();
-            }
-            if (!is_keyword) {
-              LogSymbol();
-            }
-            PropertyType type = is_getter ? kGetterProperty : kSetterProperty;
-            CheckDuplicate(&duplicate_finder, name, type, CHECK_OK);
-            ParseFunctionLiteral(CHECK_OK);
-            if (peek() != i::Token::RBRACE) {
-              Expect(i::Token::COMMA, CHECK_OK);
-            }
-            continue;  // restart the while
-        }
-        CheckDuplicate(&duplicate_finder, next, kValueProperty, CHECK_OK);
-        break;
-      }
-      case i::Token::STRING:
-        Consume(next);
-        CheckDuplicate(&duplicate_finder, next, kValueProperty, CHECK_OK);
-        GetStringSymbol();
-        break;
-      case i::Token::NUMBER:
-        Consume(next);
-        CheckDuplicate(&duplicate_finder, next, kValueProperty, CHECK_OK);
-        break;
-      default:
-        if (i::Token::IsKeyword(next)) {
-          Consume(next);
-          CheckDuplicate(&duplicate_finder, next, kValueProperty, CHECK_OK);
-        } else {
-          // Unexpected token.
-          *ok = false;
-          return Expression::Default();
-        }
-    }
-
-    Expect(i::Token::COLON, CHECK_OK);
-    ParseAssignmentExpression(true, CHECK_OK);
-
-    // TODO(1240767): Consider allowing trailing comma.
-    if (peek() != i::Token::RBRACE) Expect(i::Token::COMMA, CHECK_OK);
-  }
-  Expect(i::Token::RBRACE, CHECK_OK);
-
-  scope_->NextMaterializedLiteralIndex();
-  return Expression::Default();
-}
-
-
-PreParser::Expression PreParser::ParseRegExpLiteral(bool seen_equal,
-                                                    bool* ok) {
-  if (!scanner_->ScanRegExpPattern(seen_equal)) {
-    Next();
-    ReportMessageAt(scanner_->location(), "unterminated_regexp", NULL);
-    *ok = false;
-    return Expression::Default();
-  }
-
-  scope_->NextMaterializedLiteralIndex();
-
-  if (!scanner_->ScanRegExpFlags()) {
-    Next();
-    ReportMessageAt(scanner_->location(), "invalid_regexp_flags", NULL);
-    *ok = false;
-    return Expression::Default();
-  }
-  Next();
-  return Expression::Default();
-}
-
-
-PreParser::Arguments PreParser::ParseArguments(bool* ok) {
-  // Arguments ::
-  //   '(' (AssignmentExpression)*[','] ')'
-
-  Expect(i::Token::LPAREN, ok);
-  if (!*ok) return -1;
-  bool done = (peek() == i::Token::RPAREN);
-  int argc = 0;
-  while (!done) {
-    ParseAssignmentExpression(true, ok);
-    if (!*ok) return -1;
-    argc++;
-    done = (peek() == i::Token::RPAREN);
-    if (!done) {
-      Expect(i::Token::COMMA, ok);
-      if (!*ok) return -1;
-    }
-  }
-  Expect(i::Token::RPAREN, ok);
-  return argc;
-}
-
-
-PreParser::Expression PreParser::ParseFunctionLiteral(bool* ok) {
+PreParser::Expression PreParser::ParseFunctionLiteral(
+    Identifier function_name, Scanner::Location function_name_location,
+    bool name_is_strict_reserved, FunctionKind kind, int function_token_pos,
+    FunctionLiteral::FunctionType function_type,
+    FunctionLiteral::ArityRestriction arity_restriction, bool* ok) {
   // Function ::
   //   '(' FormalParameterList? ')' '{' FunctionBody '}'
 
   // Parse function body.
   ScopeType outer_scope_type = scope_->type();
-  bool inside_with = scope_->IsInsideWith();
-  Scope function_scope(&scope_, kFunctionScope);
+  PreParserScope function_scope(scope_, FUNCTION_SCOPE);
+  FunctionState function_state(&function_state_, &scope_, &function_scope, NULL,
+                               this->ast_value_factory());
+  function_state.set_is_generator(IsGeneratorFunction(kind));
   //  FormalParameterList ::
   //    '(' (Identifier)*[','] ')'
-  Expect(i::Token::LPAREN, CHECK_OK);
-  int start_position = scanner_->location().beg_pos;
-  bool done = (peek() == i::Token::RPAREN);
-  DuplicateFinder duplicate_finder(scanner_->unicode_cache());
+  Expect(Token::LPAREN, CHECK_OK);
+  int start_position = position();
+  DuplicateFinder duplicate_finder(scanner()->unicode_cache());
+  // We don't yet know if the function will be strict, so we cannot yet produce
+  // errors for parameter names or duplicates. However, we remember the
+  // locations of these errors if they occur and produce the errors later.
+  Scanner::Location eval_args_error_loc = Scanner::Location::invalid();
+  Scanner::Location dupe_error_loc = Scanner::Location::invalid();
+  Scanner::Location reserved_error_loc = Scanner::Location::invalid();
+
+  bool done = arity_restriction == FunctionLiteral::GETTER_ARITY ||
+      (peek() == Token::RPAREN &&
+       arity_restriction != FunctionLiteral::SETTER_ARITY);
   while (!done) {
-    Identifier id = ParseIdentifier(CHECK_OK);
-    if (!id.IsValidStrictVariable()) {
-      StrictModeIdentifierViolation(scanner_->location(),
-                                    "strict_param_name",
-                                    id,
-                                    CHECK_OK);
+    bool is_strict_reserved = false;
+    Identifier param_name =
+        ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
+    if (!eval_args_error_loc.IsValid() && param_name.IsEvalOrArguments()) {
+      eval_args_error_loc = scanner()->location();
     }
-    int prev_value;
-    if (scanner_->is_literal_ascii()) {
-      prev_value =
-          duplicate_finder.AddAsciiSymbol(scanner_->literal_ascii_string(), 1);
-    } else {
-      prev_value =
-          duplicate_finder.AddUtf16Symbol(scanner_->literal_utf16_string(), 1);
+    if (!reserved_error_loc.IsValid() && is_strict_reserved) {
+      reserved_error_loc = scanner()->location();
     }
 
-    if (prev_value != 0) {
-      SetStrictModeViolation(scanner_->location(),
-                             "strict_param_dupe",
-                             CHECK_OK);
+    int prev_value = scanner()->FindSymbol(&duplicate_finder, 1);
+
+    if (!dupe_error_loc.IsValid() && prev_value != 0) {
+      dupe_error_loc = scanner()->location();
     }
-    done = (peek() == i::Token::RPAREN);
-    if (!done) {
-      Expect(i::Token::COMMA, CHECK_OK);
-    }
+
+    if (arity_restriction == FunctionLiteral::SETTER_ARITY) break;
+    done = (peek() == Token::RPAREN);
+    if (!done) Expect(Token::COMMA, CHECK_OK);
   }
-  Expect(i::Token::RPAREN, CHECK_OK);
+  Expect(Token::RPAREN, CHECK_OK);
 
-  // Determine if the function will be lazily compiled.
-  // 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_ &&
-                             !parenthesized_function_);
+  // See Parser::ParseFunctionLiteral for more information about lazy parsing
+  // and lazy compilation.
+  bool is_lazily_parsed = (outer_scope_type == GLOBAL_SCOPE && allow_lazy() &&
+                           !parenthesized_function_);
   parenthesized_function_ = false;
 
-  Expect(i::Token::LBRACE, CHECK_OK);
-  if (is_lazily_compiled) {
+  Expect(Token::LBRACE, CHECK_OK);
+  if (is_lazily_parsed) {
     ParseLazyFunctionLiteralBody(CHECK_OK);
   } else {
-    ParseSourceElements(i::Token::RBRACE, ok);
+    ParseSourceElements(Token::RBRACE, ok);
   }
-  Expect(i::Token::RBRACE, CHECK_OK);
+  Expect(Token::RBRACE, CHECK_OK);
 
-  if (!is_classic_mode()) {
-    int end_position = scanner_->location().end_pos;
+  // Validate strict mode. We can do this only after parsing the function,
+  // since the function can declare itself strict.
+  // Concise methods use StrictFormalParameters.
+  if (strict_mode() == STRICT || IsConciseMethod(kind)) {
+    if (function_name.IsEvalOrArguments()) {
+      ReportMessageAt(function_name_location, "strict_eval_arguments");
+      *ok = false;
+      return Expression::Default();
+    }
+    if (name_is_strict_reserved) {
+      ReportMessageAt(function_name_location, "unexpected_strict_reserved");
+      *ok = false;
+      return Expression::Default();
+    }
+    if (eval_args_error_loc.IsValid()) {
+      ReportMessageAt(eval_args_error_loc, "strict_eval_arguments");
+      *ok = false;
+      return Expression::Default();
+    }
+    if (dupe_error_loc.IsValid()) {
+      ReportMessageAt(dupe_error_loc, "strict_param_dupe");
+      *ok = false;
+      return Expression::Default();
+    }
+    if (reserved_error_loc.IsValid()) {
+      ReportMessageAt(reserved_error_loc, "unexpected_strict_reserved");
+      *ok = false;
+      return Expression::Default();
+    }
+
+    int end_position = scanner()->location().end_pos;
     CheckOctalLiteral(start_position, end_position, CHECK_OK);
-    CheckDelayedStrictModeViolation(start_position, end_position, CHECK_OK);
-    return Expression::StrictFunction();
   }
 
   return Expression::Default();
@@ -1430,31 +925,30 @@
 
 
 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) {
-  int body_start = scanner_->location().beg_pos;
-  log_->PauseRecording();
-  ParseSourceElements(i::Token::RBRACE, ok);
-  log_->ResumeRecording();
+  int body_start = position();
+  ParseSourceElements(Token::RBRACE, ok);
   if (!*ok) return;
 
   // Position right after terminal '}'.
-  ASSERT_EQ(i::Token::RBRACE, scanner_->peek());
-  int body_end = scanner_->peek_location().end_pos;
+  DCHECK_EQ(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(),
-                    language_mode());
+                    function_state_->materialized_literal_count(),
+                    function_state_->expected_property_count(),
+                    strict_mode());
 }
 
 
 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) {
   // CallRuntime ::
   //   '%' Identifier Arguments
-  Expect(i::Token::MOD, CHECK_OK);
-  if (!allow_natives_syntax_) {
+  Expect(Token::MOD, CHECK_OK);
+  if (!allow_natives_syntax()) {
     *ok = false;
     return Expression::Default();
   }
-  ParseIdentifier(CHECK_OK);
+  // Allow "eval" or "arguments" for backward compatibility.
+  ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
   ParseArguments(ok);
 
   return Expression::Default();
@@ -1463,326 +957,4 @@
 #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());
-  } else {
-    log_->LogUtf16Symbol(identifier_pos, scanner_->literal_utf16_string());
-  }
-}
-
-
-PreParser::Expression PreParser::GetStringSymbol() {
-  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,
-               kUseStrictLength)) {
-    return Expression::UseStrictStringLiteral();
-  }
-  return Expression::StringLiteral();
-}
-
-
-PreParser::Identifier PreParser::GetIdentifierSymbol() {
-  LogSymbol();
-  if (scanner_->current_token() == i::Token::FUTURE_RESERVED_WORD) {
-    return Identifier::FutureReserved();
-  } else if (scanner_->current_token() ==
-             i::Token::FUTURE_STRICT_RESERVED_WORD) {
-    return Identifier::FutureStrictReserved();
-  }
-  if (scanner_->is_literal_ascii()) {
-    // Detect strict-mode poison words.
-    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)) {
-      return Identifier::Arguments();
-    }
-  }
-  return Identifier::Default();
-}
-
-
-PreParser::Identifier PreParser::ParseIdentifier(bool* ok) {
-  i::Token::Value next = Next();
-  switch (next) {
-    case i::Token::FUTURE_RESERVED_WORD: {
-      i::Scanner::Location location = scanner_->location();
-      ReportMessageAt(location.beg_pos, location.end_pos,
-                      "reserved_word", NULL);
-      *ok = false;
-      return GetIdentifierSymbol();
-    }
-    case i::Token::FUTURE_STRICT_RESERVED_WORD:
-      if (!is_classic_mode()) {
-        i::Scanner::Location location = scanner_->location();
-        ReportMessageAt(location.beg_pos, location.end_pos,
-                        "strict_reserved_word", NULL);
-        *ok = false;
-      }
-      // FALLTHROUGH
-    case i::Token::IDENTIFIER:
-      return GetIdentifierSymbol();
-    default:
-      *ok = false;
-      return Identifier::Default();
-  }
-}
-
-
-void PreParser::SetStrictModeViolation(i::Scanner::Location location,
-                                       const char* type,
-                                       bool* ok) {
-  if (!is_classic_mode()) {
-    ReportMessageAt(location, type, NULL);
-    *ok = false;
-    return;
-  }
-  // Delay report in case this later turns out to be strict code
-  // (i.e., for function names and parameters prior to a "use strict"
-  // directive).
-  // It's safe to overwrite an existing violation.
-  // It's either from a function that turned out to be non-strict,
-  // or it's in the current function (and we just need to report
-  // one error), or it's in a unclosed nesting function that wasn't
-  // strict (otherwise we would already be in strict mode).
-  strict_mode_violation_location_ = location;
-  strict_mode_violation_type_ = type;
-}
-
-
-void PreParser::CheckDelayedStrictModeViolation(int beg_pos,
-                                                int end_pos,
-                                                bool* ok) {
-  i::Scanner::Location location = strict_mode_violation_location_;
-  if (location.IsValid() &&
-      location.beg_pos > beg_pos && location.end_pos < end_pos) {
-    ReportMessageAt(location, strict_mode_violation_type_, NULL);
-    *ok = false;
-  }
-}
-
-
-void PreParser::StrictModeIdentifierViolation(i::Scanner::Location location,
-                                              const char* eval_args_type,
-                                              Identifier identifier,
-                                              bool* ok) {
-  const char* type = eval_args_type;
-  if (identifier.IsFutureReserved()) {
-    type = "reserved_word";
-  } else if (identifier.IsFutureStrictReserved()) {
-    type = "strict_reserved_word";
-  }
-  if (!is_classic_mode()) {
-    ReportMessageAt(location, type, NULL);
-    *ok = false;
-    return;
-  }
-  strict_mode_violation_location_ = location;
-  strict_mode_violation_type_ = type;
-}
-
-
-PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) {
-  i::Token::Value next = Next();
-  if (i::Token::IsKeyword(next)) {
-    int pos = scanner_->location().beg_pos;
-    const char* keyword = i::Token::String(next);
-    log_->LogAsciiSymbol(pos, i::Vector<const char>(keyword,
-                                                    i::StrLength(keyword)));
-    return Identifier::Default();
-  }
-  if (next == i::Token::IDENTIFIER ||
-      next == i::Token::FUTURE_RESERVED_WORD ||
-      next == i::Token::FUTURE_STRICT_RESERVED_WORD) {
-    return GetIdentifierSymbol();
-  }
-  *ok = false;
-  return Identifier::Default();
-}
-
-#undef CHECK_OK
-
-
-// This function reads an identifier and determines whether or not it
-// is 'get' or 'set'.
-PreParser::Identifier PreParser::ParseIdentifierNameOrGetOrSet(bool* is_get,
-                                                               bool* is_set,
-                                                               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();
-    *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;
-}
-
-
-int DuplicateFinder::AddAsciiSymbol(i::Vector<const char> key, int value) {
-  return AddSymbol(i::Vector<const byte>::cast(key), true, value);
-}
-
-int DuplicateFinder::AddUtf16Symbol(i::Vector<const uint16_t> key, int value) {
-  return AddSymbol(i::Vector<const byte>::cast(key), false, value);
-}
-
-int DuplicateFinder::AddSymbol(i::Vector<const byte> key,
-                               bool is_ascii,
-                               int value) {
-  uint32_t hash = Hash(key, is_ascii);
-  byte* encoding = BackupKey(key, is_ascii);
-  i::HashMap::Entry* entry = map_.Lookup(encoding, hash, true);
-  int old_value = static_cast<int>(reinterpret_cast<intptr_t>(entry->value));
-  entry->value =
-    reinterpret_cast<void*>(static_cast<intptr_t>(value | old_value));
-  return old_value;
-}
-
-
-int DuplicateFinder::AddNumber(i::Vector<const char> key, int value) {
-  ASSERT(key.length() > 0);
-  // Quick check for already being in canonical form.
-  if (IsNumberCanonical(key)) {
-    return AddAsciiSymbol(key, value);
-  }
-
-  int flags = i::ALLOW_HEX | i::ALLOW_OCTALS;
-  double double_value = StringToDouble(unicode_constants_, key, flags, 0.0);
-  int length;
-  const char* string;
-  if (!isfinite(double_value)) {
-    string = "Infinity";
-    length = 8;  // strlen("Infinity");
-  } else {
-    string = DoubleToCString(double_value,
-                             i::Vector<char>(number_buffer_, kBufferSize));
-    length = i::StrLength(string);
-  }
-  return AddSymbol(i::Vector<const byte>(reinterpret_cast<const byte*>(string),
-                                         length), true, value);
-}
-
-
-bool DuplicateFinder::IsNumberCanonical(i::Vector<const char> number) {
-  // Test for a safe approximation of number literals that are already
-  // in canonical form: max 15 digits, no leading zeroes, except an
-  // integer part that is a single zero, and no trailing zeros below
-  // the decimal point.
-  int pos = 0;
-  int length = number.length();
-  if (number.length() > 15) return false;
-  if (number[pos] == '0') {
-    pos++;
-  } else {
-    while (pos < length &&
-           static_cast<unsigned>(number[pos] - '0') <= ('9' - '0')) pos++;
-  }
-  if (length == pos) return true;
-  if (number[pos] != '.') return false;
-  pos++;
-  bool invalid_last_digit = true;
-  while (pos < length) {
-    byte digit = number[pos] - '0';
-    if (digit > '9' - '0') return false;
-    invalid_last_digit = (digit == 0);
-    pos++;
-  }
-  return !invalid_last_digit;
-}
-
-
-uint32_t DuplicateFinder::Hash(i::Vector<const byte> key, bool is_ascii) {
-  // Primitive hash function, almost identical to the one used
-  // for strings (except that it's seeded by the length and ASCII-ness).
-  int length = key.length();
-  uint32_t hash = (length << 1) | (is_ascii ? 1 : 0) ;
-  for (int i = 0; i < length; i++) {
-    uint32_t c = key[i];
-    hash = (hash + c) * 1025;
-    hash ^= (hash >> 6);
-  }
-  return hash;
-}
-
-
-bool DuplicateFinder::Match(void* first, void* second) {
-  // Decode lengths.
-  // Length + ASCII-bit is encoded as base 128, most significant heptet first,
-  // with a 8th bit being non-zero while there are more heptets.
-  // The value encodes the number of bytes following, and whether the original
-  // was ASCII.
-  byte* s1 = reinterpret_cast<byte*>(first);
-  byte* s2 = reinterpret_cast<byte*>(second);
-  uint32_t length_ascii_field = 0;
-  byte c1;
-  do {
-    c1 = *s1;
-    if (c1 != *s2) return false;
-    length_ascii_field = (length_ascii_field << 7) | (c1 & 0x7f);
-    s1++;
-    s2++;
-  } while ((c1 & 0x80) != 0);
-  int length = static_cast<int>(length_ascii_field >> 1);
-  return memcmp(s1, s2, length) == 0;
-}
-
-
-byte* DuplicateFinder::BackupKey(i::Vector<const byte> bytes,
-                                 bool is_ascii) {
-  uint32_t ascii_length = (bytes.length() << 1) | (is_ascii ? 1 : 0);
-  backing_store_.StartSequence();
-  // Emit ascii_length as base-128 encoded number, with the 7th bit set
-  // on the byte of every heptet except the last, least significant, one.
-  if (ascii_length >= (1 << 7)) {
-    if (ascii_length >= (1 << 14)) {
-      if (ascii_length >= (1 << 21)) {
-        if (ascii_length >= (1 << 28)) {
-          backing_store_.Add(static_cast<byte>((ascii_length >> 28) | 0x80));
-        }
-        backing_store_.Add(static_cast<byte>((ascii_length >> 21) | 0x80u));
-      }
-      backing_store_.Add(static_cast<byte>((ascii_length >> 14) | 0x80u));
-    }
-    backing_store_.Add(static_cast<byte>((ascii_length >> 7) | 0x80u));
-  }
-  backing_store_.Add(static_cast<byte>(ascii_length & 0x7f));
-
-  backing_store_.AddBlock(bytes);
-  return backing_store_.EndSequence().start();
-}
-} }  // v8::preparser
+} }  // v8::internal