Merge V8 5.2.361.47  DO NOT MERGE

https://chromium.googlesource.com/v8/v8/+/5.2.361.47

FPIIM-449

Change-Id: Ibec421b85a9b88cb3a432ada642e469fe7e78346
(cherry picked from commit bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8)
diff --git a/src/parsing/parser-base.h b/src/parsing/parser-base.h
index dde6b1d..6086f7a 100644
--- a/src/parsing/parser-base.h
+++ b/src/parsing/parser-base.h
@@ -29,6 +29,86 @@
   kDisallowLabelledFunctionStatement,
 };
 
+enum class FunctionBody { Normal, SingleExpression };
+
+enum class ParseFunctionFlags {
+  kIsNormal = 0,
+  kIsGenerator = 1,
+  kIsAsync = 2,
+  kIsDefault = 4
+};
+
+static inline ParseFunctionFlags operator|(ParseFunctionFlags lhs,
+                                           ParseFunctionFlags rhs) {
+  typedef unsigned char T;
+  return static_cast<ParseFunctionFlags>(static_cast<T>(lhs) |
+                                         static_cast<T>(rhs));
+}
+
+static inline ParseFunctionFlags& operator|=(ParseFunctionFlags& lhs,
+                                             const ParseFunctionFlags& rhs) {
+  lhs = lhs | rhs;
+  return lhs;
+}
+
+static inline bool operator&(ParseFunctionFlags bitfield,
+                             ParseFunctionFlags mask) {
+  typedef unsigned char T;
+  return static_cast<T>(bitfield) & static_cast<T>(mask);
+}
+
+enum class MethodKind {
+  Normal = 0,
+  Static = 1 << 0,
+  Generator = 1 << 1,
+  StaticGenerator = Static | Generator,
+  Async = 1 << 2,
+  StaticAsync = Static | Async,
+
+  /* Any non-ordinary method kinds */
+  SpecialMask = Generator | Async
+};
+
+inline bool IsValidMethodKind(MethodKind kind) {
+  return kind == MethodKind::Normal || kind == MethodKind::Static ||
+         kind == MethodKind::Generator || kind == MethodKind::StaticGenerator ||
+         kind == MethodKind::Async || kind == MethodKind::StaticAsync;
+}
+
+static inline MethodKind operator|(MethodKind lhs, MethodKind rhs) {
+  typedef unsigned char T;
+  return static_cast<MethodKind>(static_cast<T>(lhs) | static_cast<T>(rhs));
+}
+
+static inline MethodKind& operator|=(MethodKind& lhs, const MethodKind& rhs) {
+  lhs = lhs | rhs;
+  DCHECK(IsValidMethodKind(lhs));
+  return lhs;
+}
+
+static inline bool operator&(MethodKind bitfield, MethodKind mask) {
+  typedef unsigned char T;
+  return static_cast<T>(bitfield) & static_cast<T>(mask);
+}
+
+inline bool IsNormalMethod(MethodKind kind) {
+  return kind == MethodKind::Normal;
+}
+
+inline bool IsSpecialMethod(MethodKind kind) {
+  return kind & MethodKind::SpecialMask;
+}
+
+inline bool IsStaticMethod(MethodKind kind) {
+  return kind & MethodKind::Static;
+}
+
+inline bool IsGeneratorMethod(MethodKind kind) {
+  return kind & MethodKind::Generator;
+}
+
+inline bool IsAsyncMethod(MethodKind kind) { return kind & MethodKind::Async; }
+
 struct FormalParametersBase {
   explicit FormalParametersBase(Scope* scope) : scope(scope) {}
   Scope* scope;
@@ -98,7 +178,6 @@
              v8::Extension* extension, AstValueFactory* ast_value_factory,
              ParserRecorder* log, typename Traits::Type::Parser this_object)
       : Traits(this_object),
-        parenthesized_function_(false),
         scope_(NULL),
         function_state_(NULL),
         extension_(extension),
@@ -106,6 +185,7 @@
         ast_value_factory_(ast_value_factory),
         log_(log),
         mode_(PARSE_EAGERLY),  // Lazy mode must be set explicitly.
+        parsing_module_(false),
         stack_limit_(stack_limit),
         zone_(zone),
         scanner_(scanner),
@@ -113,13 +193,12 @@
         allow_lazy_(false),
         allow_natives_(false),
         allow_tailcalls_(false),
-        allow_harmony_sloppy_(false),
-        allow_harmony_sloppy_function_(false),
-        allow_harmony_sloppy_let_(false),
         allow_harmony_restrictive_declarations_(false),
         allow_harmony_do_expressions_(false),
+        allow_harmony_for_in_(false),
         allow_harmony_function_name_(false),
-        allow_harmony_function_sent_(false) {}
+        allow_harmony_function_sent_(false),
+        allow_harmony_async_await_(false) {}
 
 #define ALLOW_ACCESSORS(name)                           \
   bool allow_##name() const { return allow_##name##_; } \
@@ -134,13 +213,12 @@
   ALLOW_ACCESSORS(lazy);
   ALLOW_ACCESSORS(natives);
   ALLOW_ACCESSORS(tailcalls);
-  ALLOW_ACCESSORS(harmony_sloppy);
-  ALLOW_ACCESSORS(harmony_sloppy_function);
-  ALLOW_ACCESSORS(harmony_sloppy_let);
   ALLOW_ACCESSORS(harmony_restrictive_declarations);
   ALLOW_ACCESSORS(harmony_do_expressions);
+  ALLOW_ACCESSORS(harmony_for_in);
   ALLOW_ACCESSORS(harmony_function_name);
   ALLOW_ACCESSORS(harmony_function_sent);
+  ALLOW_ACCESSORS(harmony_async_await);
   SCANNER_ACCESSORS(harmony_exponentiation_operator);
 
 #undef SCANNER_ACCESSORS
@@ -195,6 +273,64 @@
     Scope* scope;
   };
 
+  class TailCallExpressionList {
+   public:
+    explicit TailCallExpressionList(Zone* zone)
+        : zone_(zone), expressions_(0, zone), has_explicit_tail_calls_(false) {}
+
+    const ZoneList<ExpressionT>& expressions() const { return expressions_; }
+    const Scanner::Location& location() const { return loc_; }
+
+    bool has_explicit_tail_calls() const { return has_explicit_tail_calls_; }
+
+    void Swap(TailCallExpressionList& other) {
+      expressions_.Swap(&other.expressions_);
+      std::swap(loc_, other.loc_);
+      std::swap(has_explicit_tail_calls_, other.has_explicit_tail_calls_);
+    }
+
+    void AddImplicitTailCall(ExpressionT expr) {
+      expressions_.Add(expr, zone_);
+    }
+
+    void AddExplicitTailCall(ExpressionT expr, const Scanner::Location& loc) {
+      if (!has_explicit_tail_calls()) {
+        loc_ = loc;
+        has_explicit_tail_calls_ = true;
+      }
+      expressions_.Add(expr, zone_);
+    }
+
+    void Append(const TailCallExpressionList& other) {
+      if (!has_explicit_tail_calls()) {
+        loc_ = other.loc_;
+        has_explicit_tail_calls_ = other.has_explicit_tail_calls_;
+      }
+      expressions_.AddAll(other.expressions_, zone_);
+    }
+
+   private:
+    Zone* zone_;
+    ZoneList<ExpressionT> expressions_;
+    Scanner::Location loc_;
+    bool has_explicit_tail_calls_;
+  };
+
+  // Defines whether tail call expressions are allowed or not.
+  enum class ReturnExprContext {
+    // We are inside return statement which is allowed to contain tail call
+    // expressions. Tail call expressions are allowed.
+    kInsideValidReturnStatement,
+
+    // We are inside a block in which tail call expressions are allowed but
+    // not yet inside a return statement.
+    kInsideValidBlock,
+
+    // Tail call expressions are not allowed in the following blocks.
+    kInsideTryBlock,
+    kInsideForInOfBody,
+  };
+
   class FunctionState BASE_EMBEDDED {
    public:
     FunctionState(FunctionState** function_state_stack, Scope** scope_stack,
@@ -230,6 +366,8 @@
     }
 
     bool is_generator() const { return IsGeneratorFunction(kind_); }
+    bool is_async_function() const { return IsAsyncFunction(kind_); }
+    bool is_resumable() const { return is_generator() || is_async_function(); }
 
     FunctionKind kind() const { return kind_; }
     FunctionState* outer() const { return outer_function_state_; }
@@ -237,7 +375,7 @@
     void set_generator_object_variable(
         typename Traits::Type::GeneratorVariable* variable) {
       DCHECK(variable != NULL);
-      DCHECK(is_generator());
+      DCHECK(is_resumable());
       generator_object_variable_ = variable;
     }
     typename Traits::Type::GeneratorVariable* generator_object_variable()
@@ -252,26 +390,43 @@
       return destructuring_assignments_to_rewrite_;
     }
 
-    List<ExpressionT>& expressions_in_tail_position() {
-      return expressions_in_tail_position_;
+    TailCallExpressionList& tail_call_expressions() {
+      return tail_call_expressions_;
     }
-    void AddExpressionInTailPosition(ExpressionT expression) {
-      if (collect_expressions_in_tail_position_) {
-        expressions_in_tail_position_.Add(expression);
+    void AddImplicitTailCallExpression(ExpressionT expression) {
+      if (return_expr_context() ==
+          ReturnExprContext::kInsideValidReturnStatement) {
+        tail_call_expressions_.AddImplicitTailCall(expression);
+      }
+    }
+    void AddExplicitTailCallExpression(ExpressionT expression,
+                                       const Scanner::Location& loc) {
+      DCHECK(expression->IsCall());
+      if (return_expr_context() ==
+          ReturnExprContext::kInsideValidReturnStatement) {
+        tail_call_expressions_.AddExplicitTailCall(expression, loc);
       }
     }
 
-    bool collect_expressions_in_tail_position() const {
-      return collect_expressions_in_tail_position_;
+    ReturnExprContext return_expr_context() const {
+      return return_expr_context_;
     }
-    void set_collect_expressions_in_tail_position(bool collect) {
-      collect_expressions_in_tail_position_ = collect;
+    void set_return_expr_context(ReturnExprContext context) {
+      return_expr_context_ = context;
     }
 
     ZoneList<ExpressionT>* non_patterns_to_rewrite() {
       return &non_patterns_to_rewrite_;
     }
 
+    void next_function_is_parenthesized(bool parenthesized) {
+      next_function_is_parenthesized_ = parenthesized;
+    }
+
+    bool this_function_is_parenthesized() const {
+      return this_function_is_parenthesized_;
+    }
+
    private:
     void AddDestructuringAssignment(DestructuringAssignment pair) {
       destructuring_assignments_to_rewrite_.Add(pair);
@@ -312,17 +467,67 @@
     Scope* outer_scope_;
 
     List<DestructuringAssignment> destructuring_assignments_to_rewrite_;
-    List<ExpressionT> expressions_in_tail_position_;
-    bool collect_expressions_in_tail_position_;
+    TailCallExpressionList tail_call_expressions_;
+    ReturnExprContext return_expr_context_;
     ZoneList<ExpressionT> non_patterns_to_rewrite_;
 
     typename Traits::Type::Factory* factory_;
 
+    // If true, the next (and immediately following) function literal is
+    // preceded by a parenthesis.
+    bool next_function_is_parenthesized_;
+
+    // The value of the parents' next_function_is_parenthesized_, as it applies
+    // to this function. Filled in by constructor.
+    bool this_function_is_parenthesized_;
+
     friend class ParserTraits;
     friend class PreParserTraits;
     friend class Checkpoint;
   };
 
+  // This scope sets current ReturnExprContext to given value.
+  class ReturnExprScope {
+   public:
+    explicit ReturnExprScope(FunctionState* function_state,
+                             ReturnExprContext return_expr_context)
+        : function_state_(function_state),
+          sav_return_expr_context_(function_state->return_expr_context()) {
+      // Don't update context if we are requested to enable tail call
+      // expressions but current block does not allow them.
+      if (return_expr_context !=
+              ReturnExprContext::kInsideValidReturnStatement ||
+          sav_return_expr_context_ == ReturnExprContext::kInsideValidBlock) {
+        function_state->set_return_expr_context(return_expr_context);
+      }
+    }
+    ~ReturnExprScope() {
+      function_state_->set_return_expr_context(sav_return_expr_context_);
+    }
+
+   private:
+    FunctionState* function_state_;
+    ReturnExprContext sav_return_expr_context_;
+  };
+
+  // Collects all return expressions at tail call position in this scope
+  // to a separate list.
+  class CollectExpressionsInTailPositionToListScope {
+   public:
+    CollectExpressionsInTailPositionToListScope(FunctionState* function_state,
+                                                TailCallExpressionList* list)
+        : function_state_(function_state), list_(list) {
+      function_state->tail_call_expressions().Swap(*list_);
+    }
+    ~CollectExpressionsInTailPositionToListScope() {
+      function_state_->tail_call_expressions().Swap(*list_);
+    }
+
+   private:
+    FunctionState* function_state_;
+    TailCallExpressionList* list_;
+  };
+
   // Annoyingly, arrow functions first parse as comma expressions, then when we
   // see the => we have to go back and reinterpret the arguments as being formal
   // parameters.  To do so we need to reset some of the parser state back to
@@ -455,7 +660,8 @@
 
   bool peek_any_identifier() {
     Token::Value next = peek();
-    return next == Token::IDENTIFIER || next == Token::FUTURE_RESERVED_WORD ||
+    return next == Token::IDENTIFIER || next == Token::ENUM ||
+           next == Token::AWAIT || next == Token::ASYNC ||
            next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
            next == Token::STATIC || next == Token::YIELD;
   }
@@ -512,6 +718,18 @@
       *ok = false;
     }
   }
+  // for now, this check just collects statistics.
+  void CheckDecimalLiteralWithLeadingZero(int* use_counts, int beg_pos,
+                                          int end_pos) {
+    Scanner::Location token_location =
+        scanner()->decimal_with_leading_zero_position();
+    if (token_location.IsValid() && beg_pos <= token_location.beg_pos &&
+        token_location.end_pos <= end_pos) {
+      scanner()->clear_decimal_with_leading_zero_position();
+      if (use_counts != nullptr)
+        ++use_counts[v8::Isolate::kDecimalWithLeadingZeroInStrictMode];
+    }
+  }
 
   inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) {
     CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kStrictOctalLiteral,
@@ -563,14 +781,10 @@
 
   LanguageMode language_mode() { return scope_->language_mode(); }
   bool is_generator() const { return function_state_->is_generator(); }
-
-  bool allow_const() {
-    return is_strict(language_mode()) || allow_harmony_sloppy();
+  bool is_async_function() const {
+    return function_state_->is_async_function();
   }
-
-  bool allow_let() {
-    return is_strict(language_mode()) || allow_harmony_sloppy_let();
-  }
+  bool is_resumable() const { return function_state_->is_resumable(); }
 
   // Report syntax errors.
   void ReportMessage(MessageTemplate::Template message, const char* arg = NULL,
@@ -627,8 +841,16 @@
 
   void ValidateBindingPattern(const ExpressionClassifier* classifier,
                               bool* ok) {
-    if (!classifier->is_valid_binding_pattern()) {
-      ReportClassifierError(classifier->binding_pattern_error());
+    if (!classifier->is_valid_binding_pattern() ||
+        !classifier->is_valid_async_binding_pattern()) {
+      const Scanner::Location& a = classifier->binding_pattern_error().location;
+      const Scanner::Location& b =
+          classifier->async_binding_pattern_error().location;
+      if (a.beg_pos < 0 || (b.beg_pos >= 0 && a.beg_pos > b.beg_pos)) {
+        ReportClassifierError(classifier->async_binding_pattern_error());
+      } else {
+        ReportClassifierError(classifier->binding_pattern_error());
+      }
       *ok = false;
     }
   }
@@ -657,7 +879,8 @@
 
   void ValidateArrowFormalParameters(const ExpressionClassifier* classifier,
                                      ExpressionT expr,
-                                     bool parenthesized_formals, bool* ok) {
+                                     bool parenthesized_formals, bool is_async,
+                                     bool* ok) {
     if (classifier->is_valid_binding_pattern()) {
       // A simple arrow formal parameter: IDENTIFIER => BODY.
       if (!this->IsIdentifier(expr)) {
@@ -677,6 +900,12 @@
       ReportClassifierError(error);
       *ok = false;
     }
+    if (is_async && !classifier->is_valid_async_arrow_formal_parameters()) {
+      const typename ExpressionClassifier::Error& error =
+          classifier->async_arrow_formal_parameters_error();
+      ReportClassifierError(error);
+      *ok = false;
+    }
   }
 
   void ValidateLetPattern(const ExpressionClassifier* classifier, bool* ok) {
@@ -686,6 +915,15 @@
     }
   }
 
+  void CheckNoTailCallExpressions(const ExpressionClassifier* classifier,
+                                  bool* ok) {
+    if (FLAG_harmony_explicit_tailcalls &&
+        classifier->has_tail_call_expression()) {
+      ReportClassifierError(classifier->tail_call_expression_error());
+      *ok = false;
+    }
+  }
+
   void ExpressionUnexpectedToken(ExpressionClassifier* classifier) {
     MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
     const char* arg;
@@ -741,27 +979,40 @@
                                  ExpressionClassifier* classifier, bool* ok);
 
   ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier,
-                                     bool* ok);
+                                     bool* is_async, bool* ok);
+  ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier,
+                                     bool* ok) {
+    bool is_async;
+    return ParsePrimaryExpression(classifier, &is_async, ok);
+  }
   ExpressionT ParseExpression(bool accept_IN, bool* ok);
   ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier,
                               bool* ok);
   ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok);
   ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set,
-                                bool* is_computed_name,
+                                bool* is_await, bool* is_computed_name,
                                 ExpressionClassifier* classifier, bool* ok);
   ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok);
   ObjectLiteralPropertyT ParsePropertyDefinition(
       ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
-      bool is_static, bool* is_computed_name, bool* has_seen_constructor,
+      MethodKind kind, bool* is_computed_name, bool* has_seen_constructor,
       ExpressionClassifier* classifier, IdentifierT* name, bool* ok);
   typename Traits::Type::ExpressionList ParseArguments(
+      Scanner::Location* first_spread_pos, bool maybe_arrow,
+      ExpressionClassifier* classifier, bool* ok);
+  typename Traits::Type::ExpressionList ParseArguments(
       Scanner::Location* first_spread_pos, ExpressionClassifier* classifier,
-      bool* ok);
+      bool* ok) {
+    return ParseArguments(first_spread_pos, false, classifier, ok);
+  }
 
   ExpressionT ParseAssignmentExpression(bool accept_IN,
                                         ExpressionClassifier* classifier,
                                         bool* ok);
-  ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok);
+  ExpressionT ParseYieldExpression(bool accept_IN,
+                                   ExpressionClassifier* classifier, bool* ok);
+  ExpressionT ParseTailCallExpression(ExpressionClassifier* classifier,
+                                      bool* ok);
   ExpressionT ParseConditionalExpression(bool accept_IN,
                                          ExpressionClassifier* classifier,
                                          bool* ok);
@@ -773,12 +1024,15 @@
   ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier,
                                           bool* ok);
   ExpressionT ParseMemberWithNewPrefixesExpression(
-      ExpressionClassifier* classifier, bool* ok);
-  ExpressionT ParseMemberExpression(ExpressionClassifier* classifier, bool* ok);
+      ExpressionClassifier* classifier, bool* is_async, bool* ok);
+  ExpressionT ParseMemberExpression(ExpressionClassifier* classifier,
+                                    bool* is_async, bool* ok);
   ExpressionT ParseMemberExpressionContinuation(
-      ExpressionT expression, ExpressionClassifier* classifier, bool* ok);
+      ExpressionT expression, bool* is_async, ExpressionClassifier* classifier,
+      bool* ok);
   ExpressionT ParseArrowFunctionLiteral(bool accept_IN,
                                         const FormalParametersT& parameters,
+                                        bool is_async,
                                         const ExpressionClassifier& classifier,
                                         bool* ok);
   ExpressionT ParseTemplateLiteral(ExpressionT tag, int start,
@@ -850,7 +1104,7 @@
     explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {}
 
     virtual void CheckProperty(Token::Value property, PropertyKind type,
-                               bool is_static, bool is_generator, bool* ok) = 0;
+                               MethodKind method_type, bool* ok) = 0;
 
     virtual ~ObjectLiteralCheckerBase() {}
 
@@ -868,8 +1122,8 @@
     explicit ObjectLiteralChecker(ParserBase* parser)
         : ObjectLiteralCheckerBase(parser), has_seen_proto_(false) {}
 
-    void CheckProperty(Token::Value property, PropertyKind type, bool is_static,
-                       bool is_generator, bool* ok) override;
+    void CheckProperty(Token::Value property, PropertyKind type,
+                       MethodKind method_type, bool* ok) override;
 
    private:
     bool IsProto() { return this->scanner()->LiteralMatches("__proto__", 9); }
@@ -883,8 +1137,8 @@
     explicit ClassLiteralChecker(ParserBase* parser)
         : ObjectLiteralCheckerBase(parser), has_seen_constructor_(false) {}
 
-    void CheckProperty(Token::Value property, PropertyKind type, bool is_static,
-                       bool is_generator, bool* ok) override;
+    void CheckProperty(Token::Value property, PropertyKind type,
+                       MethodKind method_type, bool* ok) override;
 
    private:
     bool IsConstructor() {
@@ -897,12 +1151,6 @@
     bool has_seen_constructor_;
   };
 
-  // If true, the next (and immediately following) function literal is
-  // preceded by a parenthesis.
-  // Heuristically that means that the function will be called immediately,
-  // so never lazily compile it.
-  bool parenthesized_function_;
-
   Scope* scope_;                   // Scope stack.
   FunctionState* function_state_;  // Function state stack.
   v8::Extension* extension_;
@@ -910,6 +1158,7 @@
   AstValueFactory* ast_value_factory_;  // Not owned.
   ParserRecorder* log_;
   Mode mode_;
+  bool parsing_module_;
   uintptr_t stack_limit_;
 
  private:
@@ -921,13 +1170,12 @@
   bool allow_lazy_;
   bool allow_natives_;
   bool allow_tailcalls_;
-  bool allow_harmony_sloppy_;
-  bool allow_harmony_sloppy_function_;
-  bool allow_harmony_sloppy_let_;
   bool allow_harmony_restrictive_declarations_;
   bool allow_harmony_do_expressions_;
+  bool allow_harmony_for_in_;
   bool allow_harmony_function_name_;
   bool allow_harmony_function_sent_;
+  bool allow_harmony_async_await_;
 };
 
 template <class Traits>
@@ -945,11 +1193,19 @@
       outer_function_state_(*function_state_stack),
       scope_stack_(scope_stack),
       outer_scope_(*scope_stack),
-      collect_expressions_in_tail_position_(true),
+      tail_call_expressions_(scope->zone()),
+      return_expr_context_(ReturnExprContext::kInsideValidBlock),
       non_patterns_to_rewrite_(0, scope->zone()),
-      factory_(factory) {
+      factory_(factory),
+      next_function_is_parenthesized_(false),
+      this_function_is_parenthesized_(false) {
   *scope_stack_ = scope;
   *function_state_stack = this;
+  if (outer_function_state_) {
+    this_function_is_parenthesized_ =
+        outer_function_state_->next_function_is_parenthesized_;
+    outer_function_state_->next_function_is_parenthesized_ = false;
+  }
 }
 
 
@@ -979,7 +1235,8 @@
     case Token::IDENTIFIER:
       *message = MessageTemplate::kUnexpectedTokenIdentifier;
       break;
-    case Token::FUTURE_RESERVED_WORD:
+    case Token::AWAIT:
+    case Token::ENUM:
       *message = MessageTemplate::kUnexpectedReserved;
       break;
     case Token::LET:
@@ -1054,7 +1311,8 @@
 ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
                                                bool* ok) {
   Token::Value next = Next();
-  if (next == Token::IDENTIFIER) {
+  if (next == Token::IDENTIFIER || next == Token::ASYNC ||
+      (next == Token::AWAIT && !parsing_module_)) {
     IdentifierT name = this->GetSymbol(scanner());
     // When this function is used to read a formal parameter, we don't always
     // know whether the function is going to be strict or sloppy.  Indeed for
@@ -1079,6 +1337,14 @@
             scanner()->location(), MessageTemplate::kStrictEvalArguments);
       }
     }
+    if (this->IsAwait(name)) {
+      if (is_async_function()) {
+        classifier->RecordPatternError(
+            scanner()->location(), MessageTemplate::kAwaitBindingIdentifier);
+      }
+      classifier->RecordAsyncArrowFormalParametersError(
+          scanner()->location(), MessageTemplate::kAwaitBindingIdentifier);
+    }
 
     if (classifier->duplicate_finder() != nullptr &&
         scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
@@ -1118,7 +1384,8 @@
 ParserBase<Traits>::ParseIdentifierOrStrictReservedWord(
     bool is_generator, bool* is_strict_reserved, bool* ok) {
   Token::Value next = Next();
-  if (next == Token::IDENTIFIER) {
+  if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_) ||
+      next == Token::ASYNC) {
     *is_strict_reserved = false;
   } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
              next == Token::STATIC || (next == Token::YIELD && !is_generator)) {
@@ -1134,13 +1401,13 @@
   return name;
 }
 
-
 template <class Traits>
 typename ParserBase<Traits>::IdentifierT
 ParserBase<Traits>::ParseIdentifierName(bool* ok) {
   Token::Value next = Next();
-  if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD &&
-      next != Token::LET && next != Token::STATIC && next != Token::YIELD &&
+  if (next != Token::IDENTIFIER && next != Token::ASYNC &&
+      next != Token::ENUM && next != Token::AWAIT && next != Token::LET &&
+      next != Token::STATIC && next != Token::YIELD &&
       next != Token::FUTURE_STRICT_RESERVED_WORD &&
       next != Token::ESCAPED_KEYWORD &&
       next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) {
@@ -1195,11 +1462,10 @@
 #define DUMMY )  // to make indentation work
 #undef DUMMY
 
-
 template <class Traits>
 typename ParserBase<Traits>::ExpressionT
 ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
-                                           bool* ok) {
+                                           bool* is_async, bool* ok) {
   // PrimaryExpression ::
   //   'this'
   //   'null'
@@ -1215,6 +1481,7 @@
   //   '(' Expression ')'
   //   TemplateLiteral
   //   do Block
+  //   AsyncFunctionExpression
 
   int beg_pos = peek_position();
   switch (peek()) {
@@ -1234,10 +1501,21 @@
       BindingPatternUnexpectedToken(classifier);
       return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory());
 
+    case Token::ASYNC:
+      if (allow_harmony_async_await() &&
+          !scanner()->HasAnyLineTerminatorAfterNext() &&
+          PeekAhead() == Token::FUNCTION) {
+        Consume(Token::ASYNC);
+        return this->ParseAsyncFunctionExpression(CHECK_OK);
+      }
+      // CoverCallExpressionAndAsyncArrowHead
+      *is_async = true;
+    /* falls through */
     case Token::IDENTIFIER:
     case Token::LET:
     case Token::STATIC:
     case Token::YIELD:
+    case Token::AWAIT:
     case Token::ESCAPED_STRICT_RESERVED_WORD:
     case Token::FUTURE_STRICT_RESERVED_WORD: {
       // Using eval or arguments in this context is OK even in strict mode.
@@ -1315,7 +1593,8 @@
       }
       // Heuristically try to detect immediately called functions before
       // seeing the call parentheses.
-      parenthesized_function_ = (peek() == Token::FUNCTION);
+      function_state_->next_function_is_parenthesized(peek() ==
+                                                      Token::FUNCTION);
       ExpressionT expr = this->ParseExpression(true, classifier, CHECK_OK);
       Expect(Token::RPAREN, CHECK_OK);
       return expr;
@@ -1324,11 +1603,6 @@
     case Token::CLASS: {
       BindingPatternUnexpectedToken(classifier);
       Consume(Token::CLASS);
-      if (!allow_harmony_sloppy() && is_sloppy(language_mode())) {
-        ReportMessage(MessageTemplate::kSloppyLexical);
-        *ok = false;
-        return this->EmptyExpression();
-      }
       int class_token_position = position();
       IdentifierT name = this->EmptyIdentifier();
       bool is_strict_reserved_name = false;
@@ -1382,7 +1656,6 @@
   return result;
 }
 
-
 template <class Traits>
 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
     bool accept_IN, ExpressionClassifier* classifier, bool* ok) {
@@ -1398,6 +1671,7 @@
   bool is_simple_parameter_list = this->IsIdentifier(result);
   bool seen_rest = false;
   while (peek() == Token::COMMA) {
+    CheckNoTailCallExpressions(classifier, CHECK_OK);
     if (seen_rest) {
       // At this point the production can't possibly be valid, but we don't know
       // which error to signal.
@@ -1461,6 +1735,7 @@
       int expr_pos = peek_position();
       ExpressionT argument =
           this->ParseAssignmentExpression(true, classifier, CHECK_OK);
+      CheckNoTailCallExpressions(classifier, CHECK_OK);
       elem = factory()->NewSpread(argument, start_pos, expr_pos);
 
       if (first_spread_index < 0) {
@@ -1484,6 +1759,7 @@
     } else {
       int beg_pos = peek_position();
       elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK);
+      CheckNoTailCallExpressions(classifier, CHECK_OK);
       CheckDestructuringElement(elem, classifier, beg_pos,
                                 scanner()->location().end_pos);
     }
@@ -1506,11 +1782,10 @@
   return result;
 }
 
-
 template <class Traits>
 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName(
-    IdentifierT* name, bool* is_get, bool* is_set, bool* is_computed_name,
-    ExpressionClassifier* classifier, bool* ok) {
+    IdentifierT* name, bool* is_get, bool* is_set, bool* is_await,
+    bool* is_computed_name, ExpressionClassifier* classifier, bool* ok) {
   Token::Value token = peek();
   int pos = peek_position();
 
@@ -1555,6 +1830,9 @@
     default:
       *name = ParseIdentifierName(CHECK_OK);
       scanner()->IsGetOrSet(is_get, is_set);
+      if (this->IsAwait(*name)) {
+        *is_await = true;
+      }
       break;
   }
 
@@ -1564,38 +1842,50 @@
              : factory()->NewStringLiteral(*name, pos);
 }
 
-
 template <class Traits>
 typename ParserBase<Traits>::ObjectLiteralPropertyT
 ParserBase<Traits>::ParsePropertyDefinition(
     ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
-    bool is_static, bool* is_computed_name, bool* has_seen_constructor,
+    MethodKind method_kind, bool* is_computed_name, bool* has_seen_constructor,
     ExpressionClassifier* classifier, IdentifierT* name, bool* ok) {
-  DCHECK(!in_class || is_static || has_seen_constructor != nullptr);
+  DCHECK(!in_class || IsStaticMethod(method_kind) ||
+         has_seen_constructor != nullptr);
   ExpressionT value = this->EmptyExpression();
   bool is_get = false;
   bool is_set = false;
+  bool is_await = false;
   bool is_generator = Check(Token::MUL);
+  bool is_async = false;
+  const bool is_static = IsStaticMethod(method_kind);
 
   Token::Value name_token = peek();
+
+  if (is_generator) {
+    method_kind |= MethodKind::Generator;
+  } else if (allow_harmony_async_await() && name_token == Token::ASYNC &&
+             !scanner()->HasAnyLineTerminatorAfterNext() &&
+             PeekAhead() != Token::LPAREN && PeekAhead()) {
+    is_async = true;
+  }
+
   int next_beg_pos = scanner()->peek_location().beg_pos;
   int next_end_pos = scanner()->peek_location().end_pos;
-  ExpressionT name_expression =
-      ParsePropertyName(name, &is_get, &is_set, is_computed_name, classifier,
-                        CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
+  ExpressionT name_expression = ParsePropertyName(
+      name, &is_get, &is_set, &is_await, is_computed_name, classifier,
+      CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
 
   if (fni_ != nullptr && !*is_computed_name) {
     this->PushLiteralName(fni_, *name);
   }
 
   if (!in_class && !is_generator) {
-    DCHECK(!is_static);
+    DCHECK(!IsStaticMethod(method_kind));
 
     if (peek() == Token::COLON) {
       // PropertyDefinition
       //    PropertyName ':' AssignmentExpression
       if (!*is_computed_name) {
-        checker->CheckProperty(name_token, kValueProperty, false, false,
+        checker->CheckProperty(name_token, kValueProperty, MethodKind::Normal,
                                CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
       }
       Consume(Token::COLON);
@@ -1605,12 +1895,12 @@
       CheckDestructuringElement(value, classifier, beg_pos,
                                 scanner()->location().end_pos);
 
-      return factory()->NewObjectLiteralProperty(name_expression, value, false,
-                                                 *is_computed_name);
+      return factory()->NewObjectLiteralProperty(name_expression, value,
+                                                 is_static, *is_computed_name);
     }
 
-    if (Token::IsIdentifier(name_token, language_mode(),
-                            this->is_generator()) &&
+    if (Token::IsIdentifier(name_token, language_mode(), this->is_generator(),
+                            parsing_module_) &&
         (peek() == Token::COMMA || peek() == Token::RBRACE ||
          peek() == Token::ASSIGN)) {
       // PropertyDefinition
@@ -1627,7 +1917,11 @@
         classifier->RecordLetPatternError(
             scanner()->location(), MessageTemplate::kLetInLexicalBinding);
       }
-
+      if (is_await && is_async_function()) {
+        classifier->RecordPatternError(
+            Scanner::Location(next_beg_pos, next_end_pos),
+            MessageTemplate::kAwaitBindingIdentifier);
+      }
       ExpressionT lhs = this->ExpressionFromIdentifier(
           *name, next_beg_pos, next_end_pos, scope_, factory());
       CheckDestructuringElement(lhs, classifier, next_beg_pos, next_end_pos);
@@ -1655,7 +1949,7 @@
       }
 
       return factory()->NewObjectLiteralProperty(
-          name_expression, value, ObjectLiteralProperty::COMPUTED, false,
+          name_expression, value, ObjectLiteralProperty::COMPUTED, is_static,
           false);
     }
   }
@@ -1665,20 +1959,32 @@
       Scanner::Location(next_beg_pos, scanner()->location().end_pos),
       MessageTemplate::kInvalidDestructuringTarget);
 
+  if (is_async && !IsSpecialMethod(method_kind)) {
+    DCHECK(!is_get);
+    DCHECK(!is_set);
+    bool dont_care;
+    name_expression = ParsePropertyName(
+        name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier,
+        CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
+    method_kind |= MethodKind::Async;
+  }
+
   if (is_generator || peek() == Token::LPAREN) {
     // MethodDefinition
     //    PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
     //    '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
     if (!*is_computed_name) {
-      checker->CheckProperty(name_token, kMethodProperty, is_static,
-                             is_generator,
+      checker->CheckProperty(name_token, kMethodProperty, method_kind,
                              CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
     }
 
-    FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod
-                                     : FunctionKind::kConciseMethod;
+    FunctionKind kind = is_generator
+                            ? FunctionKind::kConciseGeneratorMethod
+                            : is_async ? FunctionKind::kAsyncConciseMethod
+                                       : FunctionKind::kConciseMethod;
 
-    if (in_class && !is_static && this->IsConstructor(*name)) {
+    if (in_class && !IsStaticMethod(method_kind) &&
+        this->IsConstructor(*name)) {
       *has_seen_constructor = true;
       kind = has_extends ? FunctionKind::kSubclassConstructor
                          : FunctionKind::kBaseConstructor;
@@ -1694,13 +2000,13 @@
                                                is_static, *is_computed_name);
   }
 
-  if (in_class && name_token == Token::STATIC && !is_static) {
+  if (in_class && name_token == Token::STATIC && IsNormalMethod(method_kind)) {
     // ClassElement (static)
     //    'static' MethodDefinition
     *name = this->EmptyIdentifier();
     ObjectLiteralPropertyT property = ParsePropertyDefinition(
-        checker, true, has_extends, true, is_computed_name, nullptr, classifier,
-        name, ok);
+        checker, true, has_extends, MethodKind::Static, is_computed_name,
+        nullptr, classifier, name, ok);
     Traits::RewriteNonPattern(classifier, ok);
     return property;
   }
@@ -1714,12 +2020,11 @@
     name_token = peek();
 
     name_expression = ParsePropertyName(
-        name, &dont_care, &dont_care, is_computed_name, classifier,
+        name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier,
         CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
 
     if (!*is_computed_name) {
-      checker->CheckProperty(name_token, kAccessorProperty, is_static,
-                             is_generator,
+      checker->CheckProperty(name_token, kAccessorProperty, method_kind,
                              CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
     }
 
@@ -1769,13 +2074,12 @@
     FuncNameInferrer::State fni_state(fni_);
 
     const bool in_class = false;
-    const bool is_static = false;
     const bool has_extends = false;
     bool is_computed_name = false;
     IdentifierT name = this->EmptyIdentifier();
     ObjectLiteralPropertyT property = this->ParsePropertyDefinition(
-        &checker, in_class, has_extends, is_static, &is_computed_name, NULL,
-        classifier, &name, CHECK_OK);
+        &checker, in_class, has_extends, MethodKind::Normal, &is_computed_name,
+        NULL, classifier, &name, CHECK_OK);
 
     if (is_computed_name) {
       has_computed_names = true;
@@ -1809,11 +2113,10 @@
                                      pos);
 }
 
-
 template <class Traits>
 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
-    Scanner::Location* first_spread_arg_loc, ExpressionClassifier* classifier,
-    bool* ok) {
+    Scanner::Location* first_spread_arg_loc, bool maybe_arrow,
+    ExpressionClassifier* classifier, bool* ok) {
   // Arguments ::
   //   '(' (AssignmentExpression)*[','] ')'
 
@@ -1831,6 +2134,7 @@
 
     ExpressionT argument = this->ParseAssignmentExpression(
         true, classifier, CHECK_OK_CUSTOM(NullExpressionList));
+    CheckNoTailCallExpressions(classifier, CHECK_OK_CUSTOM(NullExpressionList));
     Traits::RewriteNonPattern(classifier, CHECK_OK_CUSTOM(NullExpressionList));
     if (is_spread) {
       if (!spread_arg.IsValid()) {
@@ -1868,7 +2172,7 @@
   }
   *first_spread_arg_loc = spread_arg;
 
-  if (spread_arg.IsValid()) {
+  if ((!maybe_arrow || peek() != Token::ARROW) && spread_arg.IsValid()) {
     // Unspread parameter sequences are translated into array literals in the
     // parser. Ensure that the number of materialized literals matches between
     // the parser and preparser
@@ -1893,25 +2197,38 @@
   int lhs_beg_pos = peek_position();
 
   if (peek() == Token::YIELD && is_generator()) {
-    return this->ParseYieldExpression(classifier, ok);
+    return this->ParseYieldExpression(accept_IN, classifier, ok);
   }
 
   FuncNameInferrer::State fni_state(fni_);
   ParserBase<Traits>::Checkpoint checkpoint(this);
   ExpressionClassifier arrow_formals_classifier(this,
                                                 classifier->duplicate_finder());
+
+  bool is_async = allow_harmony_async_await() && peek() == Token::ASYNC &&
+                  !scanner()->HasAnyLineTerminatorAfterNext();
+
   bool parenthesized_formals = peek() == Token::LPAREN;
-  if (!parenthesized_formals) {
+  if (!is_async && !parenthesized_formals) {
     ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier);
   }
   ExpressionT expression = this->ParseConditionalExpression(
       accept_IN, &arrow_formals_classifier, CHECK_OK);
+
+  if (is_async && peek_any_identifier() && PeekAhead() == Token::ARROW) {
+    // async Identifier => AsyncConciseBody
+    IdentifierT name =
+        ParseAndClassifyIdentifier(&arrow_formals_classifier, CHECK_OK);
+    expression = this->ExpressionFromIdentifier(
+        name, position(), scanner()->location().end_pos, scope_, factory());
+  }
+
   if (peek() == Token::ARROW) {
     classifier->RecordPatternError(scanner()->peek_location(),
                                    MessageTemplate::kUnexpectedToken,
                                    Token::String(Token::ARROW));
     ValidateArrowFormalParameters(&arrow_formals_classifier, expression,
-                                  parenthesized_formals, CHECK_OK);
+                                  parenthesized_formals, is_async, CHECK_OK);
     // This reads strangely, but is correct: it checks whether any
     // sub-expression of the parameter list failed to be a valid formal
     // parameter initializer. Since YieldExpressions are banned anywhere
@@ -1919,9 +2236,11 @@
     // TODO(adamk): Rename "FormalParameterInitializerError" to refer to
     // "YieldExpression", which is its only use.
     ValidateFormalParameterInitializer(&arrow_formals_classifier, ok);
+
     Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos);
-    Scope* scope =
-        this->NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction);
+    Scope* scope = this->NewScope(scope_, FUNCTION_SCOPE,
+                                  is_async ? FunctionKind::kAsyncArrowFunction
+                                           : FunctionKind::kArrowFunction);
     // Because the arrow's parameters were parsed in the outer scope, any
     // usage flags that might have been triggered there need to be copied
     // to the arrow scope.
@@ -1943,7 +2262,7 @@
           duplicate_loc);
     }
     expression = this->ParseArrowFunctionLiteral(
-        accept_IN, parameters, arrow_formals_classifier, CHECK_OK);
+        accept_IN, parameters, is_async, arrow_formals_classifier, CHECK_OK);
 
     if (fni_ != nullptr) fni_->Infer();
 
@@ -1960,8 +2279,10 @@
   classifier->Accumulate(
       &arrow_formals_classifier,
       ExpressionClassifier::StandardProductions |
-      ExpressionClassifier::FormalParametersProductions |
-      ExpressionClassifier::CoverInitializedNameProduction,
+          ExpressionClassifier::FormalParametersProductions |
+          ExpressionClassifier::CoverInitializedNameProduction |
+          ExpressionClassifier::AsyncArrowFormalParametersProduction |
+          ExpressionClassifier::AsyncBindingPatternProduction,
       false);
 
   if (!Token::IsAssignmentOp(peek())) {
@@ -1974,6 +2295,8 @@
   // Now pending non-pattern expressions must be discarded.
   arrow_formals_classifier.Discard();
 
+  CheckNoTailCallExpressions(classifier, CHECK_OK);
+
   if (IsValidPattern(expression) && peek() == Token::ASSIGN) {
     classifier->ForgiveCoverInitializedNameError();
     ValidateAssignmentPattern(classifier, CHECK_OK);
@@ -1998,10 +2321,13 @@
 
   ExpressionT right =
       this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK);
+  CheckNoTailCallExpressions(&rhs_classifier, CHECK_OK);
   Traits::RewriteNonPattern(&rhs_classifier, CHECK_OK);
   classifier->Accumulate(
-      &rhs_classifier, ExpressionClassifier::ExpressionProductions |
-                       ExpressionClassifier::CoverInitializedNameProduction);
+      &rhs_classifier,
+      ExpressionClassifier::ExpressionProductions |
+          ExpressionClassifier::CoverInitializedNameProduction |
+          ExpressionClassifier::AsyncArrowFormalParametersProduction);
 
   // TODO(1231235): We try to estimate the set of properties set by
   // constructors. We define a new property whenever there is an
@@ -2047,7 +2373,8 @@
 
 template <class Traits>
 typename ParserBase<Traits>::ExpressionT
-ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier,
+ParserBase<Traits>::ParseYieldExpression(bool accept_IN,
+                                         ExpressionClassifier* classifier,
                                          bool* ok) {
   // YieldExpression ::
   //   'yield' ([no line terminator] '*'? AssignmentExpression)?
@@ -2078,7 +2405,7 @@
         if (!delegating) break;
         // Delegating yields require an RHS; fall through.
       default:
-        expression = ParseAssignmentExpression(false, classifier, CHECK_OK);
+        expression = ParseAssignmentExpression(accept_IN, classifier, CHECK_OK);
         Traits::RewriteNonPattern(classifier, CHECK_OK);
         break;
     }
@@ -2096,6 +2423,67 @@
   return yield;
 }
 
+template <class Traits>
+typename ParserBase<Traits>::ExpressionT
+ParserBase<Traits>::ParseTailCallExpression(ExpressionClassifier* classifier,
+                                            bool* ok) {
+  // TailCallExpression::
+  //   'continue' MemberExpression  Arguments
+  //   'continue' CallExpression  Arguments
+  //   'continue' MemberExpression  TemplateLiteral
+  //   'continue' CallExpression  TemplateLiteral
+  Expect(Token::CONTINUE, CHECK_OK);
+  int pos = position();
+  int sub_expression_pos = peek_position();
+  ExpressionT expression =
+      this->ParseLeftHandSideExpression(classifier, CHECK_OK);
+  CheckNoTailCallExpressions(classifier, CHECK_OK);
+
+  Scanner::Location loc(pos, scanner()->location().end_pos);
+  if (!expression->IsCall()) {
+    Scanner::Location sub_loc(sub_expression_pos, loc.end_pos);
+    ReportMessageAt(sub_loc, MessageTemplate::kUnexpectedInsideTailCall);
+    *ok = false;
+    return Traits::EmptyExpression();
+  }
+  if (Traits::IsDirectEvalCall(expression)) {
+    Scanner::Location sub_loc(sub_expression_pos, loc.end_pos);
+    ReportMessageAt(sub_loc, MessageTemplate::kUnexpectedTailCallOfEval);
+    *ok = false;
+    return Traits::EmptyExpression();
+  }
+  if (!is_strict(language_mode())) {
+    ReportMessageAt(loc, MessageTemplate::kUnexpectedSloppyTailCall);
+    *ok = false;
+    return Traits::EmptyExpression();
+  }
+  ReturnExprContext return_expr_context =
+      function_state_->return_expr_context();
+  if (return_expr_context != ReturnExprContext::kInsideValidReturnStatement) {
+    MessageTemplate::Template msg = MessageTemplate::kNone;
+    switch (return_expr_context) {
+      case ReturnExprContext::kInsideValidReturnStatement:
+        UNREACHABLE();
+        return Traits::EmptyExpression();
+      case ReturnExprContext::kInsideValidBlock:
+        msg = MessageTemplate::kUnexpectedTailCall;
+        break;
+      case ReturnExprContext::kInsideTryBlock:
+        msg = MessageTemplate::kUnexpectedTailCallInTryBlock;
+        break;
+      case ReturnExprContext::kInsideForInOfBody:
+        msg = MessageTemplate::kUnexpectedTailCallInForInOf;
+        break;
+    }
+    ReportMessageAt(loc, msg);
+    *ok = false;
+    return Traits::EmptyExpression();
+  }
+  classifier->RecordTailCallExpressionError(
+      loc, MessageTemplate::kUnexpectedTailCall);
+  function_state_->AddExplicitTailCallExpression(expression, loc);
+  return expression;
+}
 
 // Precedence = 3
 template <class Traits>
@@ -2112,6 +2500,7 @@
   ExpressionT expression =
       this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK);
   if (peek() != Token::CONDITIONAL) return expression;
+  CheckNoTailCallExpressions(classifier, CHECK_OK);
   Traits::RewriteNonPattern(classifier, CHECK_OK);
   ArrowFormalParametersUnexpectedToken(classifier);
   BindingPatternUnexpectedToken(classifier);
@@ -2140,6 +2529,7 @@
   for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
     // prec1 >= 4
     while (Precedence(peek(), accept_IN) == prec1) {
+      CheckNoTailCallExpressions(classifier, CHECK_OK);
       Traits::RewriteNonPattern(classifier, CHECK_OK);
       BindingPatternUnexpectedToken(classifier);
       ArrowFormalParametersUnexpectedToken(classifier);
@@ -2150,6 +2540,9 @@
       const int next_prec = is_right_associative ? prec1 : prec1 + 1;
       ExpressionT y =
           ParseBinaryExpression(next_prec, accept_IN, classifier, CHECK_OK);
+      if (op != Token::OR && op != Token::AND) {
+        CheckNoTailCallExpressions(classifier, CHECK_OK);
+      }
       Traits::RewriteNonPattern(classifier, CHECK_OK);
 
       if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos,
@@ -2168,16 +2561,11 @@
           case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
           default: break;
         }
-        if (FLAG_harmony_instanceof && cmp == Token::INSTANCEOF) {
-          x = Traits::RewriteInstanceof(x, y, pos);
-        } else {
-          x = factory()->NewCompareOperation(cmp, x, y, pos);
-          if (cmp != op) {
-            // The comparison was negated - add a NOT.
-            x = factory()->NewUnaryOperation(Token::NOT, x, pos);
-          }
+        x = factory()->NewCompareOperation(cmp, x, y, pos);
+        if (cmp != op) {
+          // The comparison was negated - add a NOT.
+          x = factory()->NewUnaryOperation(Token::NOT, x, pos);
         }
-
       } else if (op == Token::EXP) {
         x = Traits::RewriteExponentiation(x, y, pos);
       } else {
@@ -2205,6 +2593,7 @@
   //   '-' UnaryExpression
   //   '~' UnaryExpression
   //   '!' UnaryExpression
+  //   [+Await] AwaitExpression[?Yield]
 
   Token::Value op = peek();
   if (Token::IsUnaryOp(op)) {
@@ -2214,6 +2603,7 @@
     op = Next();
     int pos = position();
     ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK);
+    CheckNoTailCallExpressions(classifier, CHECK_OK);
     Traits::RewriteNonPattern(classifier, CHECK_OK);
 
     if (op == Token::DELETE && is_strict(language_mode())) {
@@ -2239,6 +2629,7 @@
     op = Next();
     int beg_pos = peek_position();
     ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK);
+    CheckNoTailCallExpressions(classifier, CHECK_OK);
     expression = this->CheckAndRewriteReferenceExpression(
         expression, beg_pos, scanner()->location().end_pos,
         MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK);
@@ -2250,6 +2641,40 @@
                                         expression,
                                         position());
 
+  } else if (is_async_function() && peek() == Token::AWAIT) {
+    int beg_pos = peek_position();
+    switch (PeekAhead()) {
+      case Token::RPAREN:
+      case Token::RBRACK:
+      case Token::RBRACE:
+      case Token::ASSIGN:
+      case Token::COMMA: {
+        Next();
+        IdentifierT name = this->GetSymbol(scanner());
+
+        // Possibly async arrow formals --- record ExpressionError just in case.
+        ExpressionUnexpectedToken(classifier);
+        classifier->RecordAsyncBindingPatternError(
+            Scanner::Location(beg_pos, scanner()->location().end_pos),
+            MessageTemplate::kAwaitBindingIdentifier);
+        classifier->RecordAsyncArrowFormalParametersError(
+            Scanner::Location(beg_pos, scanner()->location().end_pos),
+            MessageTemplate::kAwaitBindingIdentifier);
+
+        return this->ExpressionFromIdentifier(
+            name, beg_pos, scanner()->location().end_pos, scope_, factory());
+      }
+      default:
+        break;
+    }
+    Consume(Token::AWAIT);
+
+    ExpressionT value = ParseUnaryExpression(classifier, CHECK_OK);
+
+    classifier->RecordFormalParameterInitializerError(
+        Scanner::Location(beg_pos, scanner()->location().end_pos),
+        MessageTemplate::kAwaitExpressionFormalParameter);
+    return Traits::RewriteAwaitExpression(value, beg_pos);
   } else {
     return this->ParsePostfixExpression(classifier, ok);
   }
@@ -2268,6 +2693,7 @@
       this->ParseLeftHandSideExpression(classifier, CHECK_OK);
   if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
       Token::IsCountOp(peek())) {
+    CheckNoTailCallExpressions(classifier, CHECK_OK);
     BindingPatternUnexpectedToken(classifier);
     ArrowFormalParametersUnexpectedToken(classifier);
 
@@ -2287,7 +2713,6 @@
   return expression;
 }
 
-
 template <class Traits>
 typename ParserBase<Traits>::ExpressionT
 ParserBase<Traits>::ParseLeftHandSideExpression(
@@ -2295,12 +2720,18 @@
   // LeftHandSideExpression ::
   //   (NewExpression | MemberExpression) ...
 
-  ExpressionT result =
-      this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK);
+  if (FLAG_harmony_explicit_tailcalls && peek() == Token::CONTINUE) {
+    return this->ParseTailCallExpression(classifier, ok);
+  }
+
+  bool is_async = false;
+  ExpressionT result = this->ParseMemberWithNewPrefixesExpression(
+      classifier, &is_async, CHECK_OK);
 
   while (true) {
     switch (peek()) {
       case Token::LBRACK: {
+        CheckNoTailCallExpressions(classifier, CHECK_OK);
         Traits::RewriteNonPattern(classifier, CHECK_OK);
         BindingPatternUnexpectedToken(classifier);
         ArrowFormalParametersUnexpectedToken(classifier);
@@ -2314,13 +2745,13 @@
       }
 
       case Token::LPAREN: {
+        CheckNoTailCallExpressions(classifier, CHECK_OK);
+        int pos;
         Traits::RewriteNonPattern(classifier, CHECK_OK);
         BindingPatternUnexpectedToken(classifier);
-        ArrowFormalParametersUnexpectedToken(classifier);
-
-        int pos;
         if (scanner()->current_token() == Token::IDENTIFIER ||
-            scanner()->current_token() == Token::SUPER) {
+            scanner()->current_token() == Token::SUPER ||
+            scanner()->current_token() == Token::ASYNC) {
           // For call of an identifier we want to report position of
           // the identifier as position of the call in the stack trace.
           pos = position();
@@ -2340,7 +2771,18 @@
         }
         Scanner::Location spread_pos;
         typename Traits::Type::ExpressionList args =
-            ParseArguments(&spread_pos, classifier, CHECK_OK);
+            ParseArguments(&spread_pos, is_async, classifier, CHECK_OK);
+
+        if (V8_UNLIKELY(is_async && peek() == Token::ARROW)) {
+          if (args->length()) {
+            // async ( Arguments ) => ...
+            return Traits::ExpressionListToExpression(args);
+          }
+          // async () => ...
+          return factory()->NewEmptyParentheses(pos);
+        }
+
+        ArrowFormalParametersUnexpectedToken(classifier);
 
         // Keep track of eval() calls since they disable all local variable
         // optimizations.
@@ -2372,6 +2814,7 @@
       }
 
       case Token::PERIOD: {
+        CheckNoTailCallExpressions(classifier, CHECK_OK);
         Traits::RewriteNonPattern(classifier, CHECK_OK);
         BindingPatternUnexpectedToken(classifier);
         ArrowFormalParametersUnexpectedToken(classifier);
@@ -2386,6 +2829,7 @@
 
       case Token::TEMPLATE_SPAN:
       case Token::TEMPLATE_TAIL: {
+        CheckNoTailCallExpressions(classifier, CHECK_OK);
         Traits::RewriteNonPattern(classifier, CHECK_OK);
         BindingPatternUnexpectedToken(classifier);
         ArrowFormalParametersUnexpectedToken(classifier);
@@ -2399,11 +2843,10 @@
   }
 }
 
-
 template <class Traits>
 typename ParserBase<Traits>::ExpressionT
 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(
-    ExpressionClassifier* classifier, bool* ok) {
+    ExpressionClassifier* classifier, bool* is_async, bool* ok) {
   // NewExpression ::
   //   ('new')+ MemberExpression
   //
@@ -2436,7 +2879,8 @@
     } else if (peek() == Token::PERIOD) {
       return ParseNewTargetExpression(CHECK_OK);
     } else {
-      result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK);
+      result = this->ParseMemberWithNewPrefixesExpression(classifier, is_async,
+                                                          CHECK_OK);
     }
     Traits::RewriteNonPattern(classifier, CHECK_OK);
     if (peek() == Token::LPAREN) {
@@ -2452,8 +2896,8 @@
         result = factory()->NewCallNew(result, args, new_pos);
       }
       // The expression can still continue with . or [ after the arguments.
-      result =
-          this->ParseMemberExpressionContinuation(result, classifier, CHECK_OK);
+      result = this->ParseMemberExpressionContinuation(result, is_async,
+                                                       classifier, CHECK_OK);
       return result;
     }
     // NewExpression without arguments.
@@ -2461,14 +2905,13 @@
                                  new_pos);
   }
   // No 'new' or 'super' keyword.
-  return this->ParseMemberExpression(classifier, ok);
+  return this->ParseMemberExpression(classifier, is_async, ok);
 }
 
-
 template <class Traits>
 typename ParserBase<Traits>::ExpressionT
 ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier,
-                                          bool* ok) {
+                                          bool* is_async, bool* ok) {
   // MemberExpression ::
   //   (PrimaryExpression | FunctionLiteral | ClassLiteral)
   //     ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
@@ -2525,10 +2968,11 @@
     const bool is_new = false;
     result = ParseSuperExpression(is_new, classifier, CHECK_OK);
   } else {
-    result = ParsePrimaryExpression(classifier, CHECK_OK);
+    result = ParsePrimaryExpression(classifier, is_async, CHECK_OK);
   }
 
-  result = ParseMemberExpressionContinuation(result, classifier, CHECK_OK);
+  result =
+      ParseMemberExpressionContinuation(result, is_async, classifier, CHECK_OK);
   return result;
 }
 
@@ -2595,16 +3039,17 @@
   return this->NewTargetExpression(scope_, factory(), pos);
 }
 
-
 template <class Traits>
 typename ParserBase<Traits>::ExpressionT
 ParserBase<Traits>::ParseMemberExpressionContinuation(
-    ExpressionT expression, ExpressionClassifier* classifier, bool* ok) {
+    ExpressionT expression, bool* is_async, ExpressionClassifier* classifier,
+    bool* ok) {
   // Parses this part of MemberExpression:
   // ('[' Expression ']' | '.' Identifier | TemplateLiteral)*
   while (true) {
     switch (peek()) {
       case Token::LBRACK: {
+        *is_async = false;
         Traits::RewriteNonPattern(classifier, CHECK_OK);
         BindingPatternUnexpectedToken(classifier);
         ArrowFormalParametersUnexpectedToken(classifier);
@@ -2621,6 +3066,7 @@
         break;
       }
       case Token::PERIOD: {
+        *is_async = false;
         Traits::RewriteNonPattern(classifier, CHECK_OK);
         BindingPatternUnexpectedToken(classifier);
         ArrowFormalParametersUnexpectedToken(classifier);
@@ -2637,6 +3083,7 @@
       }
       case Token::TEMPLATE_SPAN:
       case Token::TEMPLATE_TAIL: {
+        *is_async = false;
         Traits::RewriteNonPattern(classifier, CHECK_OK);
         BindingPatternUnexpectedToken(classifier);
         ArrowFormalParametersUnexpectedToken(classifier);
@@ -2790,28 +3237,32 @@
 template <class Traits>
 bool ParserBase<Traits>::IsNextLetKeyword() {
   DCHECK(peek() == Token::LET);
-  if (!allow_let()) {
-    return false;
-  }
   Token::Value next_next = PeekAhead();
   switch (next_next) {
     case Token::LBRACE:
     case Token::LBRACK:
     case Token::IDENTIFIER:
     case Token::STATIC:
-    case Token::LET:  // Yes, you can do let let = ... in sloppy mode
+    case Token::LET:  // `let let;` is disallowed by static semantics, but the
+                      // token must be first interpreted as a keyword in order
+                      // for those semantics to apply. This ensures that ASI is
+                      // not honored when a LineTerminator separates the
+                      // tokens.
     case Token::YIELD:
+    case Token::AWAIT:
+    case Token::ASYNC:
       return true;
+    case Token::FUTURE_STRICT_RESERVED_WORD:
+      return is_sloppy(language_mode());
     default:
       return false;
   }
 }
 
-
 template <class Traits>
 typename ParserBase<Traits>::ExpressionT
 ParserBase<Traits>::ParseArrowFunctionLiteral(
-    bool accept_IN, const FormalParametersT& formal_parameters,
+    bool accept_IN, const FormalParametersT& formal_parameters, bool is_async,
     const ExpressionClassifier& formals_classifier, bool* ok) {
   if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) {
     // ASI inserts `;` after arrow parameters if a line terminator is found.
@@ -2828,10 +3279,11 @@
   int expected_property_count = -1;
   Scanner::Location super_loc;
 
+  FunctionKind arrow_kind = is_async ? kAsyncArrowFunction : kArrowFunction;
   {
     typename Traits::Type::Factory function_factory(ast_value_factory());
     FunctionState function_state(&function_state_, &scope_,
-                                 formal_parameters.scope, kArrowFunction,
+                                 formal_parameters.scope, arrow_kind,
                                  &function_factory);
 
     function_state.SkipMaterializedLiterals(
@@ -2857,7 +3309,7 @@
       } else {
         body = this->ParseEagerFunctionBody(
             this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters,
-            kArrowFunction, FunctionLiteral::kAnonymousExpression, CHECK_OK);
+            arrow_kind, FunctionLiteral::kAnonymousExpression, CHECK_OK);
         materialized_literal_count =
             function_state.materialized_literal_count();
         expected_property_count = function_state.expected_property_count();
@@ -2865,20 +3317,31 @@
     } else {
       // Single-expression body
       int pos = position();
-      parenthesized_function_ = false;
       ExpressionClassifier classifier(this);
-      ExpressionT expression =
-          ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK);
-      Traits::RewriteNonPattern(&classifier, CHECK_OK);
+      DCHECK(ReturnExprContext::kInsideValidBlock ==
+             function_state_->return_expr_context());
+      ReturnExprScope allow_tail_calls(
+          function_state_, ReturnExprContext::kInsideValidReturnStatement);
       body = this->NewStatementList(1, zone());
-      this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK);
-      body->Add(factory()->NewReturnStatement(expression, pos), zone());
+      this->AddParameterInitializationBlock(formal_parameters, body, is_async,
+                                            CHECK_OK);
+      if (is_async) {
+        this->ParseAsyncArrowSingleExpressionBody(body, accept_IN, &classifier,
+                                                  pos, CHECK_OK);
+        Traits::RewriteNonPattern(&classifier, CHECK_OK);
+      } else {
+        ExpressionT expression =
+            ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK);
+        Traits::RewriteNonPattern(&classifier, CHECK_OK);
+        body->Add(factory()->NewReturnStatement(expression, pos), zone());
+        if (allow_tailcalls() && !is_sloppy(language_mode())) {
+          // ES6 14.6.1 Static Semantics: IsInTailPosition
+          this->MarkTailPosition(expression);
+        }
+      }
       materialized_literal_count = function_state.materialized_literal_count();
       expected_property_count = function_state.expected_property_count();
-      // ES6 14.6.1 Static Semantics: IsInTailPosition
-      if (allow_tailcalls() && !is_sloppy(language_mode())) {
-        this->MarkTailPosition(expression);
-      }
+      this->MarkCollectedTailCallExpressions();
     }
     super_loc = function_state.super_location();
 
@@ -2897,9 +3360,7 @@
       CheckStrictOctalLiteral(formal_parameters.scope->start_position(),
                               scanner()->location().end_pos, CHECK_OK);
     }
-    if (is_strict(language_mode()) || allow_harmony_sloppy()) {
-      this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK);
-    }
+    this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK);
 
     Traits::RewriteDestructuringAssignments();
   }
@@ -2909,7 +3370,7 @@
       materialized_literal_count, expected_property_count, num_parameters,
       FunctionLiteral::kNoDuplicateParameters,
       FunctionLiteral::kAnonymousExpression,
-      FunctionLiteral::kShouldLazyCompile, FunctionKind::kArrowFunction,
+      FunctionLiteral::kShouldLazyCompile, arrow_kind,
       formal_parameters.scope->start_position());
 
   function_literal->set_function_token_position(
@@ -2979,6 +3440,7 @@
 
     int expr_pos = peek_position();
     ExpressionT expression = this->ParseExpression(true, classifier, CHECK_OK);
+    CheckNoTailCallExpressions(classifier, CHECK_OK);
     Traits::RewriteNonPattern(classifier, CHECK_OK);
     Traits::AddTemplateExpression(&ts, expression);
 
@@ -3077,13 +3539,12 @@
 #undef CHECK_OK
 #undef CHECK_OK_CUSTOM
 
-
 template <typename Traits>
 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty(
-    Token::Value property, PropertyKind type, bool is_static, bool is_generator,
+    Token::Value property, PropertyKind type, MethodKind method_type,
     bool* ok) {
-  DCHECK(!is_static);
-  DCHECK(!is_generator || type == kMethodProperty);
+  DCHECK(!IsStaticMethod(method_type));
+  DCHECK(!IsSpecialMethod(method_type) || type == kMethodProperty);
 
   if (property == Token::SMI || property == Token::NUMBER) return;
 
@@ -3098,26 +3559,28 @@
   }
 }
 
-
 template <typename Traits>
 void ParserBase<Traits>::ClassLiteralChecker::CheckProperty(
-    Token::Value property, PropertyKind type, bool is_static, bool is_generator,
+    Token::Value property, PropertyKind type, MethodKind method_type,
     bool* ok) {
   DCHECK(type == kMethodProperty || type == kAccessorProperty);
 
   if (property == Token::SMI || property == Token::NUMBER) return;
 
-  if (is_static) {
+  if (IsStaticMethod(method_type)) {
     if (IsPrototype()) {
       this->parser()->ReportMessage(MessageTemplate::kStaticPrototype);
       *ok = false;
       return;
     }
   } else if (IsConstructor()) {
-    if (is_generator || type == kAccessorProperty) {
+    const bool is_generator = IsGeneratorMethod(method_type);
+    const bool is_async = IsAsyncMethod(method_type);
+    if (is_generator || is_async || type == kAccessorProperty) {
       MessageTemplate::Template msg =
           is_generator ? MessageTemplate::kConstructorIsGenerator
-                       : MessageTemplate::kConstructorIsAccessor;
+                       : is_async ? MessageTemplate::kConstructorIsAsync
+                                  : MessageTemplate::kConstructorIsAccessor;
       this->parser()->ReportMessage(msg);
       *ok = false;
       return;