Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / v8 / src / preparser.cc
index 96623b9..9fd6e23 100644 (file)
@@ -4,62 +4,40 @@
 
 #include <cmath>
 
-#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"
-
-#if V8_LIBC_MSVCRT && (_MSC_VER < 1800)
-namespace std {
-
-// Usually defined in math.h, but not in MSVC until VS2013+.
-// Abstracted to work
-int isfinite(double value);
-
-}  // namespace std
-#endif
+#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 {
 namespace internal {
 
-
 void PreParserTraits::ReportMessageAt(Scanner::Location location,
                                       const char* message,
-                                      Vector<const char*> args,
+                                      const char* arg,
                                       bool is_reference_error) {
   ReportMessageAt(location.beg_pos,
                   location.end_pos,
                   message,
-                  args.length() > 0 ? args[0] : NULL,
+                  arg,
                   is_reference_error);
 }
 
 
-void PreParserTraits::ReportMessageAt(Scanner::Location location,
-                                      const char* type,
-                                      const char* name_opt,
-                                      bool is_reference_error) {
-  pre_parser_->log_->LogMessage(location.beg_pos, location.end_pos, type,
-                                name_opt, is_reference_error);
-}
-
-
 void PreParserTraits::ReportMessageAt(int start_pos,
                                       int end_pos,
-                                      const char* type,
-                                      const char* name_opt,
+                                      const char* message,
+                                      const char* arg,
                                       bool is_reference_error) {
-  pre_parser_->log_->LogMessage(start_pos, end_pos, type, name_opt,
+  pre_parser_->log_->LogMessage(start_pos, end_pos, message, arg,
                                 is_reference_error);
 }
 
@@ -70,6 +48,10 @@ PreParserIdentifier PreParserTraits::GetSymbol(Scanner* scanner) {
   } 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::STATIC) {
+    return PreParserIdentifier::Static();
   } else if (scanner->current_token() == Token::YIELD) {
     return PreParserIdentifier::Yield();
   }
@@ -79,6 +61,17 @@ PreParserIdentifier PreParserTraits::GetSymbol(Scanner* scanner) {
   if (scanner->UnescapedLiteralMatches("arguments", 9)) {
     return PreParserIdentifier::Arguments();
   }
+  if (scanner->LiteralMatches("prototype", 9)) {
+    return PreParserIdentifier::Prototype();
+  }
+  if (scanner->LiteralMatches("constructor", 11)) {
+    return PreParserIdentifier::Constructor();
+  }
+  return PreParserIdentifier::Default();
+}
+
+
+PreParserIdentifier PreParserTraits::GetNumberAsSymbol(Scanner* scanner) {
   return PreParserIdentifier::Default();
 }
 
@@ -98,16 +91,13 @@ PreParserExpression PreParserTraits::ParseV8Intrinsic(bool* ok) {
 
 
 PreParserExpression PreParserTraits::ParseFunctionLiteral(
-    PreParserIdentifier name,
-    Scanner::Location function_name_location,
-    bool name_is_strict_reserved,
-    bool is_generator,
-    int function_token_position,
-    FunctionLiteral::FunctionType type,
-    bool* ok) {
+    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, is_generator,
-      function_token_position, type, ok);
+      name, function_name_location, name_is_strict_reserved, kind,
+      function_token_position, type, arity_restriction, ok);
 }
 
 
@@ -116,12 +106,15 @@ PreParser::PreParseResult PreParser::PreParseLazyFunction(
   log_ = log;
   // Lazy functions always have trivial outer scopes (no with/catch scopes).
   PreParserScope top_scope(scope_, GLOBAL_SCOPE);
-  FunctionState top_state(&function_state_, &scope_, &top_scope);
+  PreParserFactory top_factory(NULL);
+  FunctionState top_state(&function_state_, &scope_, &top_scope, &top_factory);
   scope_->SetStrictMode(strict_mode);
   PreParserScope function_scope(scope_, FUNCTION_SCOPE);
-  FunctionState function_state(&function_state_, &scope_, &function_scope);
+  PreParserFactory function_factory(NULL);
+  FunctionState function_state(&function_state_, &scope_, &function_scope,
+                               &function_factory);
   function_state.set_is_generator(is_generator);
-  ASSERT_EQ(Token::LBRACE, scanner()->current_token());
+  DCHECK_EQ(Token::LBRACE, scanner()->current_token());
   bool ok = true;
   int start_position = peek_position();
   ParseLazyFunctionLiteralBody(&ok);
@@ -129,7 +122,7 @@ PreParser::PreParseResult PreParser::PreParseLazyFunction(
   if (!ok) {
     ReportUnexpectedToken(scanner()->current_token());
   } else {
-    ASSERT_EQ(Token::RBRACE, scanner()->peek());
+    DCHECK_EQ(Token::RBRACE, scanner()->peek());
     if (scope_->strict_mode() == STRICT) {
       int end_pos = scanner()->location().end_pos;
       CheckOctalLiteral(start_position, end_pos, &ok);
@@ -175,9 +168,16 @@ PreParser::Statement PreParser::ParseSourceElement(bool* ok) {
   switch (peek()) {
     case Token::FUNCTION:
       return ParseFunctionDeclaration(ok);
-    case Token::LET:
+    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);
   }
@@ -245,11 +245,6 @@ PreParser::Statement PreParser::ParseStatement(bool* ok) {
     case Token::LBRACE:
       return ParseBlock(ok);
 
-    case Token::CONST:
-    case Token::LET:
-    case Token::VAR:
-      return ParseVariableStatement(kStatement, ok);
-
     case Token::SEMICOLON:
       Next();
       return Statement::Default();
@@ -294,8 +289,7 @@ PreParser::Statement PreParser::ParseStatement(bool* ok) {
       if (strict_mode() == STRICT) {
         PreParserTraits::ReportMessageAt(start_location.beg_pos,
                                          end_location.end_pos,
-                                         "strict_function",
-                                         NULL);
+                                         "strict_function");
         *ok = false;
         return Statement::Default();
       } else {
@@ -303,9 +297,22 @@ PreParser::Statement PreParser::ParseStatement(bool* ok) {
       }
     }
 
+    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);
   }
@@ -320,21 +327,31 @@ PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
   //      '{' FunctionBody '}'
   Expect(Token::FUNCTION, CHECK_OK);
   int pos = position();
-  bool is_generator = allow_generators() && Check(Token::MUL);
+  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,
-                       pos,
-                       FunctionLiteral::DECLARATION,
-                       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* '}'
@@ -394,6 +411,7 @@ PreParser::Statement PreParser::ParseVariableDeclarations(
   // ConstBinding ::
   //   BindingPattern '=' AssignmentExpression
   bool require_initializer = false;
+  bool is_strict_const = false;
   if (peek() == Token::VAR) {
     Consume(Token::VAR);
   } else if (peek() == Token::CONST) {
@@ -415,7 +433,8 @@ PreParser::Statement PreParser::ParseVariableDeclarations(
           *ok = false;
           return Statement::Default();
         }
-        require_initializer = true;
+        is_strict_const = true;
+        require_initializer = var_context != kForStatement;
       } else {
         Scanner::Location location = scanner()->peek_location();
         ReportMessageAt(location, "strict_const");
@@ -423,23 +442,9 @@ PreParser::Statement PreParser::ParseVariableDeclarations(
         return Statement::Default();
       }
     }
-  } else if (peek() == 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.
-    //
-    // TODO(rossberg): make 'let' a legal identifier in sloppy mode.
-    if (!allow_harmony_scoping() || strict_mode() == SLOPPY) {
-      ReportMessageAt(scanner()->peek_location(), "illegal_let");
-      *ok = false;
-      return Statement::Default();
-    }
+  } else if (peek() == Token::LET && strict_mode() == STRICT) {
     Consume(Token::LET);
-    if (var_context != kSourceElement &&
-        var_context != kForStatement) {
+    if (var_context != kSourceElement && var_context != kForStatement) {
       ReportMessageAt(scanner()->peek_location(), "unprotected_let");
       *ok = false;
       return Statement::Default();
@@ -459,7 +464,9 @@ PreParser::Statement PreParser::ParseVariableDeclarations(
     if (nvars > 0) Consume(Token::COMMA);
     ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
     nvars++;
-    if (peek() == Token::ASSIGN || require_initializer) {
+    if (peek() == Token::ASSIGN || require_initializer ||
+        // require initializers for multiple consts.
+        (is_strict_const && peek() == Token::COMMA)) {
       Expect(Token::ASSIGN, CHECK_OK);
       ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
       if (decl_props != NULL) *decl_props = kHasInitializers;
@@ -484,10 +491,9 @@ PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) {
   if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) {
     // Expression is a single identifier, and not, e.g., a parenthesized
     // identifier.
-    ASSERT(!expr.AsIdentifier().IsFutureReserved());
-    ASSERT(strict_mode() == SLOPPY ||
-           (!expr.AsIdentifier().IsFutureStrictReserved() &&
-            !expr.AsIdentifier().IsYield()));
+    DCHECK(!expr.AsIdentifier().IsFutureReserved());
+    DCHECK(strict_mode() == SLOPPY ||
+           !IsFutureStrictReserved(expr.AsIdentifier()));
     Consume(Token::COLON);
     return ParseStatement(ok);
     // Preparsing is disabled for extensions (because the extension details
@@ -661,8 +667,7 @@ PreParser::Statement PreParser::ParseWhileStatement(bool* ok) {
 
 bool PreParser::CheckInOrOf(bool accept_OF) {
   if (Check(Token::IN) ||
-      (allow_for_of() && accept_OF &&
-       CheckContextualKeyword(CStrVector("of")))) {
+      (accept_OF && CheckContextualKeyword(CStrVector("of")))) {
     return true;
   }
   return false;
@@ -677,14 +682,15 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) {
   Expect(Token::LPAREN, CHECK_OK);
   if (peek() != Token::SEMICOLON) {
     if (peek() == Token::VAR || peek() == Token::CONST ||
-        peek() == Token::LET) {
-      bool is_let = peek() == Token::LET;
+        (peek() == Token::LET && strict_mode() == STRICT)) {
+      bool is_lexical = peek() == Token::LET ||
+                        (peek() == Token::CONST && strict_mode() == STRICT);
       int decl_count;
       VariableDeclarationProperties decl_props = kHasNoInitializers;
       ParseVariableDeclarations(
           kForStatement, &decl_props, &decl_count, CHECK_OK);
       bool has_initializers = decl_props == kHasInitializers;
-      bool accept_IN = decl_count == 1 && !(is_let && has_initializers);
+      bool accept_IN = decl_count == 1 && !(is_lexical && has_initializers);
       bool accept_OF = !has_initializers;
       if (accept_IN && CheckInOrOf(accept_OF)) {
         ParseExpression(true, CHECK_OK);
@@ -803,26 +809,24 @@ PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) {
 
 
 PreParser::Expression PreParser::ParseFunctionLiteral(
-    Identifier function_name,
-    Scanner::Location function_name_location,
-    bool name_is_strict_reserved,
-    bool is_generator,
-    int function_token_pos,
+    Identifier function_name, Scanner::Location function_name_location,
+    bool name_is_strict_reserved, FunctionKind kind, int function_token_pos,
     FunctionLiteral::FunctionType function_type,
-    bool* ok) {
+    FunctionLiteral::ArityRestriction arity_restriction, bool* ok) {
   // Function ::
   //   '(' FormalParameterList? ')' '{' FunctionBody '}'
 
   // Parse function body.
   ScopeType outer_scope_type = scope_->type();
   PreParserScope function_scope(scope_, FUNCTION_SCOPE);
-  FunctionState function_state(&function_state_, &scope_, &function_scope);
-  function_state.set_is_generator(is_generator);
+  PreParserFactory factory(NULL);
+  FunctionState function_state(&function_state_, &scope_, &function_scope,
+                               &factory);
+  function_state.set_is_generator(IsGeneratorFunction(kind));
   //  FormalParameterList ::
   //    '(' (Identifier)*[','] ')'
   Expect(Token::LPAREN, CHECK_OK);
   int start_position = position();
-  bool done = (peek() == Token::RPAREN);
   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
@@ -830,6 +834,10 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
   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) {
     bool is_strict_reserved = false;
     Identifier param_name =
@@ -847,10 +855,9 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
       dupe_error_loc = scanner()->location();
     }
 
+    if (arity_restriction == FunctionLiteral::SETTER_ARITY) break;
     done = (peek() == Token::RPAREN);
-    if (!done) {
-      Expect(Token::COMMA, CHECK_OK);
-    }
+    if (!done) Expect(Token::COMMA, CHECK_OK);
   }
   Expect(Token::RPAREN, CHECK_OK);
 
@@ -870,7 +877,8 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
 
   // Validate strict mode. We can do this only after parsing the function,
   // since the function can declare itself strict.
-  if (strict_mode() == STRICT) {
+  // Concise methods use StrictFormalParameters.
+  if (strict_mode() == STRICT || IsConciseMethod(kind)) {
     if (function_name.IsEvalOrArguments()) {
       ReportMessageAt(function_name_location, "strict_eval_arguments");
       *ok = false;
@@ -911,7 +919,7 @@ void PreParser::ParseLazyFunctionLiteralBody(bool* ok) {
   if (!*ok) return;
 
   // Position right after terminal '}'.
-  ASSERT_EQ(Token::RBRACE, scanner()->peek());
+  DCHECK_EQ(Token::RBRACE, scanner()->peek());
   int body_end = scanner()->peek_location().end_pos;
   log_->LogFunction(body_start, body_end,
                     function_state_->materialized_literal_count(),