parser-base.h 227 KB
Newer Older
1 2 3 4
// Copyright 2012 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5 6
#ifndef V8_PARSING_PARSER_BASE_H_
#define V8_PARSING_PARSER_BASE_H_
7

8 9
#include <vector>

10
#include "src/ast/ast-source-ranges.h"
11
#include "src/ast/ast.h"
12 13
#include "src/ast/scopes.h"
#include "src/bailout-reason.h"
lpy's avatar
lpy committed
14
#include "src/base/hashmap.h"
15
#include "src/base/v8-fallthrough.h"
marja's avatar
marja committed
16
#include "src/counters.h"
yangguo's avatar
yangguo committed
17
#include "src/globals.h"
18
#include "src/log.h"
19 20 21 22 23
#include "src/messages.h"
#include "src/parsing/expression-classifier.h"
#include "src/parsing/func-name-inferrer.h"
#include "src/parsing/scanner.h"
#include "src/parsing/token.h"
24
#include "src/zone/zone-chunk-list.h"
25 26 27 28 29 30 31 32 33 34

namespace v8 {
namespace internal {

enum FunctionNameValidity {
  kFunctionNameIsStrictReserved,
  kSkipFunctionNameCheck,
  kFunctionNameValidityUnknown
};

35 36 37 38
enum AllowLabelledFunctionStatement {
  kAllowLabelledFunctionStatement,
  kDisallowLabelledFunctionStatement,
};
39

40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
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);
}

66
struct FormalParametersBase {
67
  explicit FormalParametersBase(DeclarationScope* scope) : scope(scope) {}
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82

  int num_parameters() const {
    // Don't include the rest parameter into the function's formal parameter
    // count (esp. the SharedFunctionInfo::internal_formal_parameter_count,
    // which says whether we need to create an arguments adaptor frame).
    return arity - has_rest;
  }

  void UpdateArityAndFunctionLength(bool is_optional, bool is_rest) {
    if (!is_optional && !is_rest && function_length == arity) {
      ++function_length;
    }
    ++arity;
  }

83
  DeclarationScope* scope;
84 85
  bool has_rest = false;
  bool is_simple = true;
86 87
  int function_length = 0;
  int arity = 0;
88 89
};

90 91 92 93
// Stack-allocated scope to collect source ranges from the parser.
class SourceRangeScope final {
 public:
  enum PositionKind {
94 95 96 97
    POSITION_BEG,
    POSITION_END,
    PEEK_POSITION_BEG,
    PEEK_POSITION_END,
98 99 100
  };

  SourceRangeScope(Scanner* scanner, SourceRange* range,
101 102
                   PositionKind pre_kind = PEEK_POSITION_BEG,
                   PositionKind post_kind = POSITION_END)
103 104
      : scanner_(scanner), range_(range), post_kind_(post_kind) {
    range_->start = GetPosition(pre_kind);
105
    DCHECK_NE(range_->start, kNoSourcePosition);
106 107
  }

108 109
  ~SourceRangeScope() { Finalize(); }

110 111
  const SourceRange& Finalize() {
    if (is_finalized_) return *range_;
112
    is_finalized_ = true;
113 114
    range_->end = GetPosition(post_kind_);
    DCHECK_NE(range_->end, kNoSourcePosition);
115
    return *range_;
116
  }
117 118 119

 private:
  int32_t GetPosition(PositionKind kind) {
120 121
    switch (kind) {
      case POSITION_BEG:
122
        return scanner_->location().beg_pos;
123 124 125
      case POSITION_END:
        return scanner_->location().end_pos;
      case PEEK_POSITION_BEG:
126
        return scanner_->peek_location().beg_pos;
127 128
      case PEEK_POSITION_END:
        return scanner_->peek_location().end_pos;
129 130 131 132 133 134 135 136
      default:
        UNREACHABLE();
    }
  }

  Scanner* scanner_;
  SourceRange* range_;
  PositionKind post_kind_;
137
  bool is_finalized_ = false;
138 139 140

  DISALLOW_IMPLICIT_CONSTRUCTORS(SourceRangeScope);
};
141

142 143 144 145 146 147 148 149
// ----------------------------------------------------------------------------
// The CHECK_OK macro is a convenient macro to enforce error
// handling for functions that may fail (by returning !*ok).
//
// CAUTION: This macro appends extra statements after a call,
// thus it must never be used where only a single statement
// is correct (e.g. an if statement branch w/o braces)!

150 151
#define CHECK_OK_CUSTOM(x, ...) ok);       \
  if (!*ok) return impl()->x(__VA_ARGS__); \
152 153 154 155
  ((void)0
#define DUMMY )  // to make indentation work
#undef DUMMY

156
// Used in functions where the return type is ExpressionT.
157
#define CHECK_OK CHECK_OK_CUSTOM(NullExpression)
158

159 160 161 162 163 164
#define CHECK_OK_VOID ok); \
  if (!*ok) return;        \
  ((void)0
#define DUMMY )  // to make indentation work
#undef DUMMY

165 166 167 168 169
// Common base class template shared between parser and pre-parser.
// The Impl parameter is the actual class of the parser/pre-parser,
// following the Curiously Recurring Template Pattern (CRTP).
// The structure of the parser objects is roughly the following:
//
170 171
//   // A structure template containing type definitions, needed to
//   // avoid a cyclic dependency.
172
//   template <typename Impl>
173 174
//   struct ParserTypes;
//
175 176 177 178 179
//   // The parser base object, which should just implement pure
//   // parser behavior.  The Impl parameter is the actual derived
//   // class (according to CRTP), which implements impure parser
//   // behavior.
//   template <typename Impl>
180
//   class ParserBase { ... };
181 182 183 184 185
//
//   // And then, for each parser variant (e.g., parser, preparser, etc):
//   class Parser;
//
//   template <>
186
//   class ParserTypes<Parser> { ... };
187 188 189
//
//   class Parser : public ParserBase<Parser> { ... };
//
190 191 192 193 194 195 196 197 198 199
// The parser base object implements pure parsing, according to the
// language grammar.  Different parser implementations may exhibit
// different parser-driven behavior that is not considered as pure
// parsing, e.g., early error detection and reporting, AST generation, etc.

// The ParserTypes structure encapsulates the differences in the
// types used in parsing methods.  E.g., Parser methods use Expression*
// and PreParser methods use PreParserExpression.  For any given parser
// implementation class Impl, it is expected to contain the following typedefs:
//
200
// template <>
201 202 203 204 205 206 207 208 209
// struct ParserTypes<Impl> {
//   // Synonyms for ParserBase<Impl> and Impl, respectively.
//   typedef Base;
//   typedef Impl;
//   // Return types for traversing functions.
//   typedef Identifier;
//   typedef Expression;
//   typedef FunctionLiteral;
//   typedef ObjectLiteralProperty;
210
//   typedef ClassLiteralProperty;
211
//   typedef ExpressionList;
212 213
//   typedef ObjectPropertyList;
//   typedef ClassPropertyList;
214
//   typedef FormalParameters;
215
//   typedef Statement;
216
//   typedef StatementList;
217
//   typedef Block;
218
//   typedef BreakableStatement;
219
//   typedef ForStatement;
220
//   typedef IterationStatement;
221 222
//   // For constructing objects returned by the traversing functions.
//   typedef Factory;
223 224 225
//   // For other implementation-specific tasks.
//   typedef Target;
//   typedef TargetScope;
226 227
// };

228
template <typename Impl>
229
struct ParserTypes;
230 231

template <typename Impl>
232
class ParserBase {
233
 public:
234 235 236
  // Shorten type names defined by ParserTypes<Impl>.
  typedef ParserTypes<Impl> Types;
  typedef typename Types::Identifier IdentifierT;
237
  typedef typename Types::Expression ExpressionT;
238 239
  typedef typename Types::FunctionLiteral FunctionLiteralT;
  typedef typename Types::ObjectLiteralProperty ObjectLiteralPropertyT;
240
  typedef typename Types::ClassLiteralProperty ClassLiteralPropertyT;
241
  typedef typename Types::Suspend SuspendExpressionT;
242
  typedef typename Types::RewritableExpression RewritableExpressionT;
243 244
  typedef typename Types::ExpressionList ExpressionListT;
  typedef typename Types::FormalParameters FormalParametersT;
245
  typedef typename Types::Statement StatementT;
246
  typedef typename Types::StatementList StatementListT;
247
  typedef typename Types::Block BlockT;
248
  typedef typename Types::ForStatement ForStatementT;
249 250
  typedef typename v8::internal::ExpressionClassifier<Types>
      ExpressionClassifier;
251

252 253 254 255
  // All implementation-specific methods must be called through this.
  Impl* impl() { return static_cast<Impl*>(this); }
  const Impl* impl() const { return static_cast<const Impl*>(this); }

256
  ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit,
257
             v8::Extension* extension, AstValueFactory* ast_value_factory,
258
             PendingCompilationErrorHandler* pending_error_handler,
259 260
             RuntimeCallStats* runtime_call_stats, Logger* logger,
             int script_id, bool parsing_module, bool parsing_on_main_thread)
261
      : scope_(nullptr),
262
        original_scope_(nullptr),
263
        function_state_(nullptr),
264
        extension_(extension),
265
        fni_(nullptr),
266
        ast_value_factory_(ast_value_factory),
267
        ast_node_factory_(ast_value_factory, zone),
268
        runtime_call_stats_(runtime_call_stats),
269
        logger_(logger),
270
        parsing_on_main_thread_(parsing_on_main_thread),
271
        parsing_module_(parsing_module),
272
        stack_limit_(stack_limit),
273
        pending_error_handler_(pending_error_handler),
274
        zone_(zone),
275
        classifier_(nullptr),
276
        scanner_(scanner),
277
        default_eager_compile_hint_(FunctionLiteral::kShouldLazyCompile),
278
        function_literal_id_(0),
279
        script_id_(script_id),
280
        allow_natives_(false),
281
        allow_harmony_do_expressions_(false),
282
        allow_harmony_public_fields_(false),
283
        allow_harmony_static_fields_(false),
284
        allow_harmony_dynamic_import_(false),
285
        allow_harmony_import_meta_(false),
286 287
        allow_harmony_private_fields_(false),
        allow_eval_cache_(true) {}
288 289 290 291 292 293 294

#define ALLOW_ACCESSORS(name)                           \
  bool allow_##name() const { return allow_##name##_; } \
  void set_allow_##name(bool allow) { allow_##name##_ = allow; }

  ALLOW_ACCESSORS(natives);
  ALLOW_ACCESSORS(harmony_do_expressions);
295
  ALLOW_ACCESSORS(harmony_public_fields);
296
  ALLOW_ACCESSORS(harmony_static_fields);
297
  ALLOW_ACCESSORS(harmony_dynamic_import);
298
  ALLOW_ACCESSORS(harmony_import_meta);
299
  ALLOW_ACCESSORS(eval_cache);
300

301 302
#undef ALLOW_ACCESSORS

303 304 305 306 307 308
  bool allow_harmony_bigint() const {
    return scanner()->allow_harmony_bigint();
  }
  void set_allow_harmony_bigint(bool allow) {
    scanner()->set_allow_harmony_bigint(allow);
  }
309 310 311 312 313 314
  bool allow_harmony_numeric_separator() const {
    return scanner()->allow_harmony_numeric_separator();
  }
  void set_allow_harmony_numeric_separator(bool allow) {
    scanner()->set_allow_harmony_numeric_separator(allow);
  }
315

316 317 318 319 320 321 322
  bool allow_harmony_private_fields() const {
    return scanner()->allow_harmony_private_fields();
  }
  void set_allow_harmony_private_fields(bool allow) {
    scanner()->set_allow_harmony_private_fields(allow);
  }

323 324
  uintptr_t stack_limit() const { return stack_limit_; }

325 326
  void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; }

327 328 329 330 331 332 333 334 335
  void set_default_eager_compile_hint(
      FunctionLiteral::EagerCompileHint eager_compile_hint) {
    default_eager_compile_hint_ = eager_compile_hint;
  }

  FunctionLiteral::EagerCompileHint default_eager_compile_hint() const {
    return default_eager_compile_hint_;
  }

336 337 338 339 340 341 342
  int GetNextFunctionLiteralId() { return ++function_literal_id_; }
  int GetLastFunctionLiteralId() const { return function_literal_id_; }

  void SkipFunctionLiterals(int delta) { function_literal_id_ += delta; }

  void ResetFunctionLiteralId() { function_literal_id_ = 0; }

343 344 345 346
  // The Zone where the parsing outputs are stored.
  Zone* main_zone() const { return ast_value_factory()->zone(); }

  // The current Zone, which might be the main zone or a temporary Zone.
347 348
  Zone* zone() const { return zone_; }

349
 protected:
350 351
  friend class v8::internal::ExpressionClassifier<ParserTypes<Impl>>;

352 353 354 355 356
  enum AllowRestrictedIdentifiers {
    kAllowRestrictedIdentifiers,
    kDontAllowRestrictedIdentifiers
  };

357
  enum LazyParsingResult { kLazyParsingComplete, kLazyParsingAborted };
358

359 360 361 362 363
  enum VariableDeclarationContext {
    kStatementListItem,
    kStatement,
    kForStatement
  };
364

365 366
  class ClassLiteralChecker;
  class ObjectLiteralChecker;
367 368

  // ---------------------------------------------------------------------------
369 370 371 372 373
  // BlockState and FunctionState implement the parser's scope stack.
  // The parser's current scope is in scope_. BlockState and FunctionState
  // constructors push on the scope stack and the destructors pop. They are also
  // used to hold the parser's per-funcion state.
  class BlockState BASE_EMBEDDED {
374
   public:
375 376 377
    BlockState(Scope** scope_stack, Scope* scope)
        : scope_stack_(scope_stack), outer_scope_(*scope_stack) {
      *scope_stack_ = scope;
378
    }
379

380 381 382
    BlockState(Zone* zone, Scope** scope_stack)
        : BlockState(scope_stack,
                     new (zone) Scope(zone, *scope_stack, BLOCK_SCOPE)) {}
383

384
    ~BlockState() { *scope_stack_ = outer_scope_; }
385 386

   private:
387 388
    Scope** const scope_stack_;
    Scope* const outer_scope_;
389 390
  };

391
  class FunctionState final : public BlockState {
392
   public:
393 394
    FunctionState(FunctionState** function_state_stack, Scope** scope_stack,
                  DeclarationScope* scope);
395 396
    ~FunctionState();

397
    DeclarationScope* scope() const { return scope_->AsDeclarationScope(); }
398

399 400 401
    void AddProperty() { expected_property_count_++; }
    int expected_property_count() { return expected_property_count_; }

402 403 404 405 406
    void DisableOptimization(BailoutReason reason) {
      dont_optimize_reason_ = reason;
    }
    BailoutReason dont_optimize_reason() { return dont_optimize_reason_; }

407 408
    void AddSuspend() { suspend_count_++; }
    int suspend_count() const { return suspend_count_; }
409
    bool CanSuspend() const { return suspend_count_ > 0; }
410

411
    FunctionKind kind() const { return scope()->function_kind(); }
412

413 414 415 416
    void RewindDestructuringAssignments(int pos) {
      destructuring_assignments_to_rewrite_.Rewind(pos);
    }

417 418 419
    void AdoptDestructuringAssignmentsFromParentState(int pos) {
      const auto& outer_assignments =
          outer_function_state_->destructuring_assignments_to_rewrite_;
420 421 422 423 424
      DCHECK_GE(outer_assignments.size(), pos);
      auto it = outer_assignments.begin();
      it.Advance(pos);
      for (; it != outer_assignments.end(); ++it) {
        auto expr = *it;
425
        expr->set_scope(scope_);
426
        destructuring_assignments_to_rewrite_.push_back(expr);
427
      }
428
      outer_function_state_->RewindDestructuringAssignments(pos);
429 430
    }

431
    const ZoneChunkList<RewritableExpressionT>&
432
    destructuring_assignments_to_rewrite() const {
433 434 435
      return destructuring_assignments_to_rewrite_;
    }

436
    ZoneList<typename ExpressionClassifier::Error>* GetReportedErrorList() {
437 438 439
      return &reported_errors_;
    }

440 441
    bool next_function_is_likely_called() const {
      return next_function_is_likely_called_;
442 443
    }

444 445 446 447
    bool previous_function_was_likely_called() const {
      return previous_function_was_likely_called_;
    }

448 449
    void set_next_function_is_likely_called() {
      next_function_is_likely_called_ = true;
450 451
    }

452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475
    void RecordFunctionOrEvalCall() { contains_function_or_eval_ = true; }
    bool contains_function_or_eval() const {
      return contains_function_or_eval_;
    }

    class FunctionOrEvalRecordingScope {
     public:
      explicit FunctionOrEvalRecordingScope(FunctionState* state)
          : state_(state) {
        prev_value_ = state->contains_function_or_eval_;
        state->contains_function_or_eval_ = false;
      }
      ~FunctionOrEvalRecordingScope() {
        bool found = state_->contains_function_or_eval_;
        if (!found) {
          state_->contains_function_or_eval_ = prev_value_;
        }
      }

     private:
      FunctionState* state_;
      bool prev_value_;
    };

476
   private:
477
    void AddDestructuringAssignment(RewritableExpressionT expr) {
478
      destructuring_assignments_to_rewrite_.push_back(expr);
479 480
    }

481 482 483
    // Properties count estimation.
    int expected_property_count_;

484 485 486
    // How many suspends are needed for this function.
    int suspend_count_;

487 488
    FunctionState** function_state_stack_;
    FunctionState* outer_function_state_;
489
    DeclarationScope* scope_;
490

491
    ZoneChunkList<RewritableExpressionT> destructuring_assignments_to_rewrite_;
492

493
    ZoneList<typename ExpressionClassifier::Error> reported_errors_;
494

495 496 497
    // A reason, if any, why this function should not be optimized.
    BailoutReason dont_optimize_reason_;

498
    // Record whether the next (=== immediately following) function literal is
499 500 501 502
    // preceded by a parenthesis / exclamation mark. Also record the previous
    // state.
    // These are managed by the FunctionState constructor; the caller may only
    // call set_next_function_is_likely_called.
503
    bool next_function_is_likely_called_;
504
    bool previous_function_was_likely_called_;
505

506 507 508
    // Track if a function or eval occurs within this FunctionState
    bool contains_function_or_eval_;

509
    friend Impl;
510 511
  };

512
  struct DeclarationDescriptor {
513
    enum Kind { NORMAL, PARAMETER, FOR_EACH };
514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530
    Scope* scope;
    VariableMode mode;
    int declaration_pos;
    int initialization_pos;
    Kind declaration_kind;
  };

  struct DeclarationParsingResult {
    struct Declaration {
      Declaration(ExpressionT pattern, int initializer_position,
                  ExpressionT initializer)
          : pattern(pattern),
            initializer_position(initializer_position),
            initializer(initializer) {}

      ExpressionT pattern;
      int initializer_position;
531
      int value_beg_position = kNoSourcePosition;
532 533 534 535
      ExpressionT initializer;
    };

    DeclarationParsingResult()
536
        : first_initializer_loc(Scanner::Location::invalid()),
537 538 539
          bindings_loc(Scanner::Location::invalid()) {}

    DeclarationDescriptor descriptor;
540
    std::vector<Declaration> declarations;
541 542 543 544
    Scanner::Location first_initializer_loc;
    Scanner::Location bindings_loc;
  };

545 546 547
  struct CatchInfo {
   public:
    explicit CatchInfo(ParserBase* parser)
548 549
        : name(parser->impl()->NullIdentifier()),
          pattern(parser->impl()->NullExpression()),
550
          scope(nullptr),
551 552
          init_block(parser->impl()->NullStatement()),
          inner_block(parser->impl()->NullStatement()),
553
          bound_names(1, parser->zone()) {}
554 555 556 557 558
    IdentifierT name;
    ExpressionT pattern;
    Scope* scope;
    BlockT init_block;
    BlockT inner_block;
559
    ZonePtrList<const AstRawString> bound_names;
560 561
  };

562 563 564 565 566
  struct ForInfo {
   public:
    explicit ForInfo(ParserBase* parser)
        : bound_names(1, parser->zone()),
          mode(ForEachStatement::ENUMERATE),
567
          position(kNoSourcePosition),
568
          parsing_result() {}
569
    ZonePtrList<const AstRawString> bound_names;
570
    ForEachStatement::VisitMode mode;
571
    int position;
572 573 574
    DeclarationParsingResult parsing_result;
  };

575 576 577
  struct ClassInfo {
   public:
    explicit ClassInfo(ParserBase* parser)
578
        : variable(nullptr),
579
          extends(parser->impl()->NullExpression()),
580
          properties(parser->impl()->NewClassPropertyList(4)),
581
          static_fields(parser->impl()->NewClassPropertyList(4)),
582
          instance_fields(parser->impl()->NewClassPropertyList(4)),
583
          constructor(parser->impl()->NullExpression()),
584
          has_seen_constructor(false),
585
          has_name_static_property(false),
586
          has_static_computed_names(false),
587
          has_static_class_fields(false),
588
          has_instance_class_fields(false),
589
          is_anonymous(false),
590
          static_fields_scope(nullptr),
591 592
          instance_fields_scope(nullptr),
          computed_field_count(0) {}
593
    Variable* variable;
594 595
    ExpressionT extends;
    typename Types::ClassPropertyList properties;
596
    typename Types::ClassPropertyList static_fields;
597
    typename Types::ClassPropertyList instance_fields;
598
    FunctionLiteralT constructor;
599

600 601 602 603 604 605
    bool has_seen_constructor;
    bool has_name_static_property;
    bool has_static_computed_names;
    bool has_static_class_fields;
    bool has_instance_class_fields;
    bool is_anonymous;
606 607
    DeclarationScope* static_fields_scope;
    DeclarationScope* instance_fields_scope;
608
    int computed_field_count;
609 610
  };

611 612 613
  const AstRawString* ClassFieldVariableName(AstValueFactory* ast_value_factory,
                                             int index) {
    std::string name = ".class-field-" + std::to_string(index);
614
    return ast_value_factory->GetOneByteString(name.c_str());
615 616
  }

617
  DeclarationScope* NewScriptScope() const {
618
    return new (zone()) DeclarationScope(zone(), ast_value_factory());
619 620
  }

621
  DeclarationScope* NewVarblockScope() const {
622 623 624
    return new (zone()) DeclarationScope(zone(), scope(), BLOCK_SCOPE);
  }

625
  ModuleScope* NewModuleScope(DeclarationScope* parent) const {
626
    return new (zone()) ModuleScope(parent, ast_value_factory());
627 628
  }

629
  DeclarationScope* NewEvalScope(Scope* parent) const {
630
    return new (zone()) DeclarationScope(zone(), parent, EVAL_SCOPE);
631 632
  }

633
  Scope* NewScope(ScopeType scope_type) const {
634 635 636 637 638 639
    return NewScopeWithParent(scope(), scope_type);
  }

  // This constructor should only be used when absolutely necessary. Most scopes
  // should automatically use scope() as parent, and be fine with
  // NewScope(ScopeType) above.
640
  Scope* NewScopeWithParent(Scope* parent, ScopeType scope_type) const {
641 642 643 644
    // Must always use the specific constructors for the blacklisted scope
    // types.
    DCHECK_NE(FUNCTION_SCOPE, scope_type);
    DCHECK_NE(SCRIPT_SCOPE, scope_type);
645
    DCHECK_NE(MODULE_SCOPE, scope_type);
646
    DCHECK_NOT_NULL(parent);
647
    return new (zone()) Scope(zone(), parent, scope_type);
648 649
  }

650 651 652 653 654
  // Creates a function scope that always allocates in zone(). The function
  // scope itself is either allocated in zone() or in target_zone if one is
  // passed in.
  DeclarationScope* NewFunctionScope(FunctionKind kind,
                                     Zone* target_zone = nullptr) const {
655
    DCHECK(ast_value_factory());
656 657 658
    if (target_zone == nullptr) target_zone = zone();
    DeclarationScope* result = new (target_zone)
        DeclarationScope(zone(), scope(), FUNCTION_SCOPE, kind);
659 660 661 662

    // Record presence of an inner function scope
    function_state_->RecordFunctionOrEvalCall();

663
    // TODO(verwaest): Move into the DeclarationScope constructor.
664 665 666
    if (!IsArrowFunction(kind)) {
      result->DeclareDefaultFunctionVariables(ast_value_factory());
    }
667 668 669
    return result;
  }

670 671 672 673 674 675 676
  V8_INLINE DeclarationScope* GetDeclarationScope() const {
    return scope()->GetDeclarationScope();
  }
  V8_INLINE DeclarationScope* GetClosureScope() const {
    return scope()->GetClosureScope();
  }

677 678
  Scanner* scanner() const { return scanner_; }
  AstValueFactory* ast_value_factory() const { return ast_value_factory_; }
679 680
  int position() const { return scanner_->location().beg_pos; }
  int peek_position() const { return scanner_->peek_location().beg_pos; }
681 682 683 684
  bool stack_overflow() const {
    return pending_error_handler()->stack_overflow();
  }
  void set_stack_overflow() { pending_error_handler()->set_stack_overflow(); }
685 686
  int script_id() { return script_id_; }
  void set_script_id(int id) { script_id_ = id; }
687

688
  V8_INLINE Token::Value peek() {
689
    if (stack_overflow()) return Token::ILLEGAL;
690 691 692
    return scanner()->peek();
  }

693 694 695 696 697 698 699
  // Returns the position past the following semicolon (if it exists), and the
  // position past the end of the current token otherwise.
  int PositionAfterSemicolon() {
    return (peek() == Token::SEMICOLON) ? scanner_->peek_location().end_pos
                                        : scanner_->location().end_pos;
  }

700
  V8_INLINE Token::Value PeekAhead() {
701
    if (stack_overflow()) return Token::ILLEGAL;
702 703 704
    return scanner()->PeekAhead();
  }

705
  V8_INLINE Token::Value Next() {
706
    if (stack_overflow()) return Token::ILLEGAL;
707 708 709 710 711
    {
      if (GetCurrentStackPosition() < stack_limit_) {
        // Any further calls to Next or peek will return the illegal token.
        // The current call must return the next token, which might already
        // have been peek'ed.
712
        set_stack_overflow();
713 714 715 716 717 718 719 720 721
      }
    }
    return scanner()->Next();
  }

  void Consume(Token::Value token) {
    Token::Value next = Next();
    USE(next);
    USE(token);
722
    DCHECK_EQ(next, token);
723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749
  }

  bool Check(Token::Value token) {
    Token::Value next = peek();
    if (next == token) {
      Consume(next);
      return true;
    }
    return false;
  }

  void Expect(Token::Value token, bool* ok) {
    Token::Value next = Next();
    if (next != token) {
      ReportUnexpectedToken(next);
      *ok = false;
    }
  }

  void ExpectSemicolon(bool* ok) {
    // Check for automatic semicolon insertion according to
    // the rules given in ECMA-262, section 7.9, page 21.
    Token::Value tok = peek();
    if (tok == Token::SEMICOLON) {
      Next();
      return;
    }
750
    if (scanner()->HasLineTerminatorBeforeNext() || tok == Token::RBRACE ||
751 752 753
        tok == Token::EOS) {
      return;
    }
754 755

    *ok = false;
756 757
    if (scanner()->current_token() == Token::AWAIT && !is_async_function()) {
      ReportMessageAt(scanner()->location(),
758 759 760 761
                      MessageTemplate::kAwaitNotInAsyncFunction, kSyntaxError);
      return;
    }

762
    ReportUnexpectedToken(Next());
763 764
  }

765
  // Dummy functions, just useful as arguments to CHECK_OK_CUSTOM.
766
  static void Void() {}
767 768 769 770
  template <typename T>
  static T Return(T result) {
    return result;
  }
771

772
  bool peek_any_identifier() { return Token::IsAnyIdentifier(peek()); }
773

774 775
  bool CheckContextualKeyword(Token::Value token) {
    if (PeekContextualKeyword(token)) {
776 777 778 779 780 781
      Consume(Token::IDENTIFIER);
      return true;
    }
    return false;
  }

782 783
  bool PeekContextualKeyword(Token::Value token) {
    DCHECK(Token::IsContextualKeyword(token));
784
    return peek() == Token::IDENTIFIER &&
785
           scanner()->next_contextual_token() == token;
786 787
  }

788 789
  void ExpectMetaProperty(Token::Value property_name, const char* full_name,
                          int pos, bool* ok);
790

791 792
  void ExpectContextualKeyword(Token::Value token, bool* ok) {
    DCHECK(Token::IsContextualKeyword(token));
793
    Expect(Token::IDENTIFIER, CHECK_OK_CUSTOM(Void));
794
    if (scanner()->current_contextual_token() != token) {
795 796 797 798 799
      ReportUnexpectedToken(scanner()->current_token());
      *ok = false;
    }
  }

800
  bool CheckInOrOf(ForEachStatement::VisitMode* visit_mode) {
801
    if (Check(Token::IN)) {
802
      *visit_mode = ForEachStatement::ENUMERATE;
803
      return true;
804
    } else if (CheckContextualKeyword(Token::OF)) {
805 806 807 808 809 810
      *visit_mode = ForEachStatement::ITERATE;
      return true;
    }
    return false;
  }

811
  bool PeekInOrOf() {
812
    return peek() == Token::IN || PeekContextualKeyword(Token::OF);
813 814
  }

815
  // Checks whether an octal literal was last seen between beg_pos and end_pos.
816 817
  // Only called for strict mode strings.
  void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) {
818 819 820
    Scanner::Location octal = scanner()->octal_position();
    if (octal.IsValid() && beg_pos <= octal.beg_pos &&
        octal.end_pos <= end_pos) {
821
      MessageTemplate::Template message = scanner()->octal_message();
822
      DCHECK_NE(message, MessageTemplate::kNone);
823
      impl()->ReportMessageAt(octal, message);
824
      scanner()->clear_octal_position();
825 826 827
      if (message == MessageTemplate::kStrictDecimalWithLeadingZero) {
        impl()->CountUsage(v8::Isolate::kDecimalWithLeadingZeroInStrictMode);
      }
828 829 830 831
      *ok = false;
    }
  }

832
  // Checks if an octal literal or an invalid hex or unicode escape sequence
833 834 835
  // appears in the current template literal token. In the presence of such,
  // either returns false or reports an error, depending on should_throw.
  // Otherwise returns true.
836
  inline bool CheckTemplateEscapes(bool should_throw, bool* ok) {
837 838
    DCHECK(scanner()->current_token() == Token::TEMPLATE_SPAN ||
           scanner()->current_token() == Token::TEMPLATE_TAIL);
839 840 841
    if (!scanner()->has_invalid_template_escape()) {
      return true;
    }
842

843 844 845 846 847 848 849
    // Handle error case(s)
    if (should_throw) {
      impl()->ReportMessageAt(scanner()->invalid_template_escape_location(),
                              scanner()->invalid_template_escape_message());
      *ok = false;
    }
    return false;
850 851
  }

852
  void CheckDestructuringElement(ExpressionT element, int beg_pos, int end_pos);
853 854 855 856 857 858

  // Checking the name of a function literal. This has to be done after parsing
  // the function, since the function can declare itself strict.
  void CheckFunctionName(LanguageMode language_mode, IdentifierT function_name,
                         FunctionNameValidity function_name_validity,
                         const Scanner::Location& function_name_loc, bool* ok) {
859
    if (impl()->IsNull(function_name)) return;
860 861 862 863
    if (function_name_validity == kSkipFunctionNameCheck) return;
    // The function name needs to be checked in strict mode.
    if (is_sloppy(language_mode)) return;

864
    if (impl()->IsEvalOrArguments(function_name)) {
865
      impl()->ReportMessageAt(function_name_loc,
866 867 868 869 870
                              MessageTemplate::kStrictEvalArguments);
      *ok = false;
      return;
    }
    if (function_name_validity == kFunctionNameIsStrictReserved) {
871
      impl()->ReportMessageAt(function_name_loc,
872 873 874 875 876 877 878 879 880 881 882 883 884
                              MessageTemplate::kUnexpectedStrictReserved);
      *ok = false;
      return;
    }
  }

  // Determine precedence of given token.
  static int Precedence(Token::Value token, bool accept_IN) {
    if (token == Token::IN && !accept_IN)
      return 0;  // 0 precedence will terminate binary expression parsing
    return Token::Precedence(token);
  }

885
  typename Types::Factory* factory() { return &ast_node_factory_; }
886

887 888 889
  DeclarationScope* GetReceiverScope() const {
    return scope()->GetReceiverScope();
  }
890
  LanguageMode language_mode() { return scope()->language_mode(); }
891 892 893 894
  void RaiseLanguageMode(LanguageMode mode) {
    LanguageMode old = scope()->language_mode();
    impl()->SetLanguageMode(scope(), old > mode ? old : mode);
  }
895 896 897
  bool is_generator() const {
    return IsGeneratorFunction(function_state_->kind());
  }
898
  bool is_async_function() const {
899 900
    return IsAsyncFunction(function_state_->kind());
  }
901 902 903
  bool is_async_generator() const {
    return IsAsyncGeneratorFunction(function_state_->kind());
  }
904 905
  bool is_resumable() const {
    return IsResumableFunction(function_state_->kind());
906
  }
907

908 909 910 911 912 913 914
  const PendingCompilationErrorHandler* pending_error_handler() const {
    return pending_error_handler_;
  }
  PendingCompilationErrorHandler* pending_error_handler() {
    return pending_error_handler_;
  }

915
  // Report syntax errors.
916
  void ReportMessage(MessageTemplate::Template message) {
917
    Scanner::Location source_location = scanner()->location();
918 919
    impl()->ReportMessageAt(source_location, message,
                            static_cast<const char*>(nullptr), kSyntaxError);
920 921
  }

922 923
  template <typename T>
  void ReportMessage(MessageTemplate::Template message, T arg,
924 925
                     ParseErrorType error_type = kSyntaxError) {
    Scanner::Location source_location = scanner()->location();
926
    impl()->ReportMessageAt(source_location, message, arg, error_type);
927 928 929 930 931
  }

  void ReportMessageAt(Scanner::Location location,
                       MessageTemplate::Template message,
                       ParseErrorType error_type) {
932 933
    impl()->ReportMessageAt(location, message,
                            static_cast<const char*>(nullptr), error_type);
934 935 936
  }

  void GetUnexpectedTokenMessage(
937 938
      Token::Value token, MessageTemplate::Template* message,
      Scanner::Location* location, const char** arg,
939 940 941 942 943 944 945
      MessageTemplate::Template default_ = MessageTemplate::kUnexpectedToken);

  void ReportUnexpectedToken(Token::Value token);
  void ReportUnexpectedTokenAt(
      Scanner::Location location, Token::Value token,
      MessageTemplate::Template message = MessageTemplate::kUnexpectedToken);

946 947
  void ReportClassifierError(
      const typename ExpressionClassifier::Error& error) {
948
    impl()->ReportMessageAt(error.location, error.message, error.arg);
949 950
  }

951 952 953
  void ValidateExpression(bool* ok) {
    if (!classifier()->is_valid_expression()) {
      ReportClassifierError(classifier()->expression_error());
954 955 956 957
      *ok = false;
    }
  }

958 959 960
  void ValidateFormalParameterInitializer(bool* ok) {
    if (!classifier()->is_valid_formal_parameter_initializer()) {
      ReportClassifierError(classifier()->formal_parameter_initializer_error());
961 962 963 964
      *ok = false;
    }
  }

965 966 967
  void ValidateBindingPattern(bool* ok) {
    if (!classifier()->is_valid_binding_pattern()) {
      ReportClassifierError(classifier()->binding_pattern_error());
968 969 970 971
      *ok = false;
    }
  }

972 973 974
  void ValidateAssignmentPattern(bool* ok) {
    if (!classifier()->is_valid_assignment_pattern()) {
      ReportClassifierError(classifier()->assignment_pattern_error());
975 976 977 978
      *ok = false;
    }
  }

979
  void ValidateFormalParameters(LanguageMode language_mode,
980 981
                                bool allow_duplicates, bool* ok) {
    if (!allow_duplicates &&
982 983
        !classifier()->is_valid_formal_parameter_list_without_duplicates()) {
      ReportClassifierError(classifier()->duplicate_formal_parameter_error());
984 985
      *ok = false;
    } else if (is_strict(language_mode) &&
986 987
               !classifier()->is_valid_strict_mode_formal_parameters()) {
      ReportClassifierError(classifier()->strict_mode_formal_parameter_error());
988 989 990 991
      *ok = false;
    }
  }

992
  bool IsValidArrowFormalParametersStart(Token::Value token) {
993
    return Token::IsAnyIdentifier(token) || token == Token::LPAREN;
994 995
  }

996
  void ValidateArrowFormalParameters(ExpressionT expr,
997 998
                                     bool parenthesized_formals, bool is_async,
                                     bool* ok) {
999
    if (classifier()->is_valid_binding_pattern()) {
1000
      // A simple arrow formal parameter: IDENTIFIER => BODY.
1001
      if (!impl()->IsIdentifier(expr)) {
1002
        impl()->ReportMessageAt(scanner()->location(),
1003 1004 1005 1006
                                MessageTemplate::kUnexpectedToken,
                                Token::String(scanner()->current_token()));
        *ok = false;
      }
1007
    } else if (!classifier()->is_valid_arrow_formal_parameters()) {
1008 1009 1010 1011
      // If after parsing the expr, we see an error but the expression is
      // neither a valid binding pattern nor a valid parenthesized formal
      // parameter list, show the "arrow formal parameters" error if the formals
      // started with a parenthesis, and the binding pattern error otherwise.
1012
      const typename ExpressionClassifier::Error& error =
1013 1014
          parenthesized_formals ? classifier()->arrow_formal_parameters_error()
                                : classifier()->binding_pattern_error();
1015 1016 1017
      ReportClassifierError(error);
      *ok = false;
    }
1018
    if (is_async && !classifier()->is_valid_async_arrow_formal_parameters()) {
1019
      const typename ExpressionClassifier::Error& error =
1020
          classifier()->async_arrow_formal_parameters_error();
1021 1022 1023
      ReportClassifierError(error);
      *ok = false;
    }
1024 1025
  }

1026 1027 1028
  void ValidateLetPattern(bool* ok) {
    if (!classifier()->is_valid_let_pattern()) {
      ReportClassifierError(classifier()->let_pattern_error());
1029 1030 1031 1032
      *ok = false;
    }
  }

1033
  void BindingPatternUnexpectedToken() {
1034 1035
    MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
    const char* arg;
1036 1037
    Scanner::Location location = scanner()->peek_location();
    GetUnexpectedTokenMessage(peek(), &message, &location, &arg);
1038
    classifier()->RecordBindingPatternError(location, message, arg);
1039 1040
  }

1041
  void ArrowFormalParametersUnexpectedToken() {
1042 1043
    MessageTemplate::Template message = MessageTemplate::kUnexpectedToken;
    const char* arg;
1044 1045
    Scanner::Location location = scanner()->peek_location();
    GetUnexpectedTokenMessage(peek(), &message, &location, &arg);
1046
    classifier()->RecordArrowFormalParametersError(location, message, arg);
1047 1048
  }

1049 1050 1051 1052 1053 1054
  // Recursive descent functions.
  // All ParseXXX functions take as the last argument an *ok parameter
  // which is set to false if parsing failed; it is unchanged otherwise.
  // By making the 'exception handling' explicit, we are forced to check
  // for failure at the call sites. The family of CHECK_OK* macros can
  // be useful for this.
1055 1056 1057 1058 1059 1060 1061

  // Parses an identifier that is valid for the current scope, in particular it
  // fails on strict mode future reserved keywords in a strict scope. If
  // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or
  // "arguments" as identifier even in strict mode (this is needed in cases like
  // "var foo = eval;").
  IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok);
1062
  IdentifierT ParseAndClassifyIdentifier(bool* ok);
1063
  // Parses an identifier or a strict mode future reserved word, and indicate
1064
  // whether it is strict mode future reserved. Allows passing in function_kind
1065
  // for the case of parsing the identifier in a function expression, where the
1066 1067 1068
  // relevant "function_kind" bit is of the function being parsed, not the
  // containing function.
  IdentifierT ParseIdentifierOrStrictReservedWord(FunctionKind function_kind,
1069
                                                  bool* is_strict_reserved,
1070
                                                  bool* is_await, bool* ok);
1071
  IdentifierT ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved,
1072 1073 1074
                                                  bool* is_await, bool* ok) {
    return ParseIdentifierOrStrictReservedWord(
        function_state_->kind(), is_strict_reserved, is_await, ok);
1075 1076
  }

1077
  V8_INLINE IdentifierT ParseIdentifierName(bool* ok);
1078

1079 1080
  ExpressionT ParseIdentifierNameOrPrivateName(bool* ok);

1081
  ExpressionT ParseRegExpLiteral(bool* ok);
1082

1083 1084
  ExpressionT ParsePrimaryExpression(bool* is_async, bool* ok);
  ExpressionT ParsePrimaryExpression(bool* ok) {
1085
    bool is_async;
1086
    return ParsePrimaryExpression(&is_async, ok);
1087
  }
1088

1089 1090
  // Use when parsing an expression that is known to not be a pattern or part
  // of a pattern.
1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102
  V8_INLINE ExpressionT ParseExpression(bool accept_IN, bool* ok);

  // This method does not wrap the parsing of the expression inside a
  // new expression classifier; it uses the top-level classifier instead.
  // It should be used whenever we're parsing something with the "cover"
  // grammar that recognizes both patterns and non-patterns (which roughly
  // corresponds to what's inside the parentheses generated by the symbol
  // "CoverParenthesizedExpressionAndArrowParameterList" in the ES 2017
  // specification).
  ExpressionT ParseExpressionCoverGrammar(bool accept_IN, bool* ok);

  ExpressionT ParseArrayLiteral(bool* ok);
1103 1104

  enum class PropertyKind {
1105 1106
    kAccessorGetterProperty,
    kAccessorSetterProperty,
1107 1108 1109
    kValueProperty,
    kShorthandProperty,
    kMethodProperty,
1110
    kClassField,
1111
    kSpreadProperty,
1112 1113 1114
    kNotSet
  };

1115 1116 1117 1118 1119
  inline static bool IsAccessor(PropertyKind kind) {
    return IsInRange(kind, PropertyKind::kAccessorGetterProperty,
                     PropertyKind::kAccessorSetterProperty);
  }

1120 1121
  bool SetPropertyKindFromToken(Token::Value token, PropertyKind* kind);
  ExpressionT ParsePropertyName(IdentifierT* name, PropertyKind* kind,
1122 1123
                                bool* is_generator, bool* is_async,
                                bool* is_computed_name, bool* ok);
1124
  ExpressionT ParseObjectLiteral(bool* ok);
1125
  ClassLiteralPropertyT ParseClassPropertyDefinition(
1126 1127
      ClassLiteralChecker* checker, ClassInfo* class_info,
      IdentifierT* property_name, bool has_extends, bool* is_computed_name,
1128
      ClassLiteralProperty::Kind* property_kind, bool* is_static, bool* ok);
1129 1130
  ExpressionT ParseClassFieldInitializer(ClassInfo* class_info, bool is_static,
                                         bool* ok);
1131
  ObjectLiteralPropertyT ParseObjectPropertyDefinition(
1132 1133
      ObjectLiteralChecker* checker, bool* is_computed_name,
      bool* is_rest_property, bool* ok);
1134
  ExpressionListT ParseArguments(Scanner::Location* first_spread_pos,
1135 1136
                                 bool maybe_arrow,
                                 bool* is_simple_parameter_list, bool* ok);
1137 1138
  ExpressionListT ParseArguments(Scanner::Location* first_spread_pos,
                                 bool* ok) {
1139
    return ParseArguments(first_spread_pos, false, nullptr, ok);
1140 1141 1142 1143
  }

  ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok);
  ExpressionT ParseYieldExpression(bool accept_IN, bool* ok);
1144
  V8_INLINE ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok);
1145 1146
  ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
  ExpressionT ParseUnaryExpression(bool* ok);
1147 1148
  V8_INLINE ExpressionT ParsePostfixExpression(bool* ok);
  V8_INLINE ExpressionT ParseLeftHandSideExpression(bool* ok);
1149
  ExpressionT ParseMemberWithNewPrefixesExpression(bool* is_async, bool* ok);
1150 1151 1152
  V8_INLINE ExpressionT ParseMemberExpression(bool* is_async, bool* ok);
  V8_INLINE ExpressionT ParseMemberExpressionContinuation(
      ExpressionT expression, bool* is_async, bool* ok);
1153 1154 1155 1156 1157

  // `rewritable_length`: length of the destructuring_assignments_to_rewrite()
  // queue in the parent function state, prior to parsing of formal parameters.
  // If the arrow function is lazy, any items added during formal parameter
  // parsing are removed from the queue.
1158 1159
  ExpressionT ParseArrowFunctionLiteral(bool accept_IN,
                                        const FormalParametersT& parameters,
1160
                                        int rewritable_length, bool* ok);
1161 1162 1163
  void ParseSingleExpressionFunctionBody(StatementListT body, bool is_async,
                                         bool accept_IN, bool* ok);
  void ParseAsyncFunctionBody(Scope* scope, StatementListT body, bool* ok);
1164
  ExpressionT ParseAsyncFunctionLiteral(bool* ok);
1165 1166 1167 1168
  ExpressionT ParseClassLiteral(IdentifierT name,
                                Scanner::Location class_name_location,
                                bool name_is_strict_reserved,
                                int class_token_pos, bool* ok);
1169 1170
  ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool tagged,
                                   bool* ok);
1171
  ExpressionT ParseSuperExpression(bool is_new, bool* ok);
1172
  ExpressionT ParseImportExpressions(bool* ok);
1173 1174
  ExpressionT ParseNewTargetExpression(bool* ok);

1175
  V8_INLINE void ParseFormalParameter(FormalParametersT* parameters, bool* ok);
1176
  void ParseFormalParameterList(FormalParametersT* parameters, bool* ok);
1177 1178 1179
  void CheckArityRestrictions(int param_count, FunctionKind function_type,
                              bool has_rest, int formals_start_pos,
                              int formals_end_pos, bool* ok);
1180

1181 1182
  BlockT ParseVariableDeclarations(VariableDeclarationContext var_context,
                                   DeclarationParsingResult* parsing_result,
1183
                                   ZonePtrList<const AstRawString>* names,
1184
                                   bool* ok);
1185 1186
  StatementT ParseAsyncFunctionDeclaration(
      ZonePtrList<const AstRawString>* names, bool default_export, bool* ok);
1187
  StatementT ParseFunctionDeclaration(bool* ok);
1188
  StatementT ParseHoistableDeclaration(ZonePtrList<const AstRawString>* names,
1189 1190
                                       bool default_export, bool* ok);
  StatementT ParseHoistableDeclaration(int pos, ParseFunctionFlags flags,
1191
                                       ZonePtrList<const AstRawString>* names,
1192
                                       bool default_export, bool* ok);
1193
  StatementT ParseClassDeclaration(ZonePtrList<const AstRawString>* names,
1194 1195
                                   bool default_export, bool* ok);
  StatementT ParseNativeDeclaration(bool* ok);
1196

1197 1198 1199 1200 1201 1202
  // Consumes the ending }.
  void ParseFunctionBody(StatementListT result, IdentifierT function_name,
                         int pos, const FormalParametersT& parameters,
                         FunctionKind kind,
                         FunctionLiteral::FunctionType function_type, bool* ok);

1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213
  // Under some circumstances, we allow preparsing to abort if the preparsed
  // function is "long and trivial", and fully parse instead. Our current
  // definition of "long and trivial" is:
  // - over kLazyParseTrialLimit statements
  // - all starting with an identifier (i.e., no if, for, while, etc.)
  static const int kLazyParseTrialLimit = 200;

  // TODO(nikolaos, marja): The first argument should not really be passed
  // by value. The method is expected to add the parsed statements to the
  // list. This works because in the case of the parser, StatementListT is
  // a pointer whereas the preparser does not really modify the body.
1214
  V8_INLINE void ParseStatementList(StatementListT body, Token::Value end_token,
1215 1216 1217 1218 1219
                                    bool* ok) {
    LazyParsingResult result = ParseStatementList(body, end_token, false, ok);
    USE(result);
    DCHECK_EQ(result, kLazyParsingComplete);
  }
1220 1221 1222
  V8_INLINE LazyParsingResult ParseStatementList(StatementListT body,
                                                 Token::Value end_token,
                                                 bool may_abort, bool* ok);
1223
  StatementT ParseStatementListItem(bool* ok);
1224 1225 1226 1227 1228 1229

  StatementT ParseStatement(ZonePtrList<const AstRawString>* labels,
                            ZonePtrList<const AstRawString>* own_labels,
                            bool* ok) {
    return ParseStatement(labels, own_labels,
                          kDisallowLabelledFunctionStatement, ok);
1230
  }
1231
  StatementT ParseStatement(ZonePtrList<const AstRawString>* labels,
1232
                            ZonePtrList<const AstRawString>* own_labels,
1233 1234
                            AllowLabelledFunctionStatement allow_function,
                            bool* ok);
1235
  BlockT ParseBlock(ZonePtrList<const AstRawString>* labels, bool* ok);
1236

1237 1238 1239
  // Parse a SubStatement in strict mode, or with an extra block scope in
  // sloppy mode to handle
  // ES#sec-functiondeclarations-in-ifstatement-statement-clauses
1240
  StatementT ParseScopedStatement(ZonePtrList<const AstRawString>* labels,
1241
                                  bool* ok);
1242 1243

  StatementT ParseVariableStatement(VariableDeclarationContext var_context,
1244
                                    ZonePtrList<const AstRawString>* names,
1245 1246 1247 1248 1249
                                    bool* ok);

  // Magical syntax support.
  ExpressionT ParseV8Intrinsic(bool* ok);

1250 1251
  ExpressionT ParseDoExpression(bool* ok);

1252 1253
  StatementT ParseDebuggerStatement(bool* ok);

1254
  StatementT ParseExpressionOrLabelledStatement(
1255
      ZonePtrList<const AstRawString>* labels,
1256
      ZonePtrList<const AstRawString>* own_labels,
1257
      AllowLabelledFunctionStatement allow_function, bool* ok);
1258 1259
  StatementT ParseIfStatement(ZonePtrList<const AstRawString>* labels,
                              bool* ok);
1260
  StatementT ParseContinueStatement(bool* ok);
1261
  StatementT ParseBreakStatement(ZonePtrList<const AstRawString>* labels,
1262 1263
                                 bool* ok);
  StatementT ParseReturnStatement(bool* ok);
1264
  StatementT ParseWithStatement(ZonePtrList<const AstRawString>* labels,
1265
                                bool* ok);
1266
  StatementT ParseDoWhileStatement(ZonePtrList<const AstRawString>* labels,
1267
                                   ZonePtrList<const AstRawString>* own_labels,
1268
                                   bool* ok);
1269
  StatementT ParseWhileStatement(ZonePtrList<const AstRawString>* labels,
1270
                                 ZonePtrList<const AstRawString>* own_labels,
1271 1272
                                 bool* ok);
  StatementT ParseThrowStatement(bool* ok);
1273
  StatementT ParseSwitchStatement(ZonePtrList<const AstRawString>* labels,
1274
                                  bool* ok);
1275
  V8_INLINE StatementT ParseTryStatement(bool* ok);
1276
  StatementT ParseForStatement(ZonePtrList<const AstRawString>* labels,
1277
                               ZonePtrList<const AstRawString>* own_labels,
1278
                               bool* ok);
1279
  StatementT ParseForEachStatementWithDeclarations(
1280
      int stmt_pos, ForInfo* for_info, ZonePtrList<const AstRawString>* labels,
1281 1282
      ZonePtrList<const AstRawString>* own_labels, Scope* inner_block_scope,
      bool* ok);
1283 1284
  StatementT ParseForEachStatementWithoutDeclarations(
      int stmt_pos, ExpressionT expression, int lhs_beg_pos, int lhs_end_pos,
1285 1286
      ForInfo* for_info, ZonePtrList<const AstRawString>* labels,
      ZonePtrList<const AstRawString>* own_labels, bool* ok);
1287

1288 1289
  // Parse a C-style for loop: 'for (<init>; <cond>; <next>) { ... }'
  // "for (<init>;" is assumed to have been parser already.
1290 1291 1292 1293
  ForStatementT ParseStandardForLoop(
      int stmt_pos, ZonePtrList<const AstRawString>* labels,
      ZonePtrList<const AstRawString>* own_labels, ExpressionT* cond,
      StatementT* next, StatementT* body, bool* ok);
1294
  // Same as the above, but handles those cases where <init> is a
1295 1296 1297
  // lexical variable declaration.
  StatementT ParseStandardForLoopWithLexicalDeclarations(
      int stmt_pos, StatementT init, ForInfo* for_info,
1298 1299
      ZonePtrList<const AstRawString>* labels,
      ZonePtrList<const AstRawString>* own_labels, bool* ok);
1300
  StatementT ParseForAwaitStatement(ZonePtrList<const AstRawString>* labels,
1301
                                    ZonePtrList<const AstRawString>* own_labels,
1302
                                    bool* ok);
1303

1304
  bool IsNextLetKeyword();
1305
  bool IsTrivialExpression();
1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319

  // Checks if the expression is a valid reference expression (e.g., on the
  // left-hand side of assignments). Although ruled out by ECMA as early errors,
  // we allow calls for web compatibility and rewrite them to a runtime throw.
  ExpressionT CheckAndRewriteReferenceExpression(
      ExpressionT expression, int beg_pos, int end_pos,
      MessageTemplate::Template message, bool* ok);
  ExpressionT CheckAndRewriteReferenceExpression(
      ExpressionT expression, int beg_pos, int end_pos,
      MessageTemplate::Template message, ParseErrorType type, bool* ok);

  bool IsValidReferenceExpression(ExpressionT expression);

  bool IsAssignableIdentifier(ExpressionT expression) {
1320
    if (!impl()->IsIdentifier(expression)) return false;
1321
    if (is_strict(language_mode()) &&
1322
        impl()->IsEvalOrArguments(impl()->AsIdentifier(expression))) {
1323 1324 1325 1326 1327
      return false;
    }
    return true;
  }

1328 1329 1330 1331
  bool IsValidPattern(ExpressionT expression) {
    return expression->IsObjectLiteral() || expression->IsArrayLiteral();
  }

1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347
  // Due to hoisting, the value of a 'var'-declared variable may actually change
  // even if the code contains only the "initial" assignment, namely when that
  // assignment occurs inside a loop.  For example:
  //
  //   let i = 10;
  //   do { var x = i } while (i--):
  //
  // As a simple and very conservative approximation of this, we explicitly mark
  // as maybe-assigned any non-lexical variable whose initializing "declaration"
  // does not syntactically occur in the function scope.  (In the example above,
  // it occurs in a block scope.)
  //
  // Note that non-lexical variables include temporaries, which may also get
  // assigned inside a loop due to the various rewritings that the parser
  // performs.
  //
1348 1349 1350 1351 1352 1353
  // This also handles marking of loop variables in for-in and for-of loops,
  // as determined by declaration_kind.
  //
  static void MarkLoopVariableAsAssigned(
      Scope* scope, Variable* var,
      typename DeclarationDescriptor::Kind declaration_kind);
1354

1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386
  FunctionKind FunctionKindForImpl(bool is_method, bool is_generator,
                                   bool is_async) {
    static const FunctionKind kFunctionKinds[][2][2] = {
        {
            // is_method=false
            {// is_generator=false
             FunctionKind::kNormalFunction, FunctionKind::kAsyncFunction},
            {// is_generator=true
             FunctionKind::kGeneratorFunction,
             FunctionKind::kAsyncGeneratorFunction},
        },
        {
            // is_method=true
            {// is_generator=false
             FunctionKind::kConciseMethod, FunctionKind::kAsyncConciseMethod},
            {// is_generator=true
             FunctionKind::kConciseGeneratorMethod,
             FunctionKind::kAsyncConciseGeneratorMethod},
        }};
    return kFunctionKinds[is_method][is_generator][is_async];
  }

  inline FunctionKind FunctionKindFor(bool is_generator, bool is_async) {
    const bool kIsMethod = false;
    return FunctionKindForImpl(kIsMethod, is_generator, is_async);
  }

  inline FunctionKind MethodKindFor(bool is_generator, bool is_async) {
    const bool kIsMethod = true;
    return FunctionKindForImpl(kIsMethod, is_generator, is_async);
  }

1387 1388 1389
  // Keep track of eval() calls since they disable all local variable
  // optimizations. This checks if expression is an eval call, and if yes,
  // forwards the information to scope.
1390 1391
  Call::PossiblyEval CheckPossibleEvalCall(ExpressionT expression,
                                           Scope* scope) {
1392 1393
    if (impl()->IsIdentifier(expression) &&
        impl()->IsEval(impl()->AsIdentifier(expression))) {
1394
      scope->RecordInnerScopeEvalCall();
1395
      function_state_->RecordFunctionOrEvalCall();
1396 1397 1398
      if (is_sloppy(scope->language_mode())) {
        // For sloppy scopes we also have to record the call at function level,
        // in case it includes declarations that will be hoisted.
1399
        scope->GetDeclarationScope()->RecordEvalCall();
1400
      }
1401 1402 1403 1404 1405 1406 1407

      // This call is only necessary to track evals that may be
      // inside arrow function parameter lists. In that case,
      // Scope::Snapshot::Reparent will move this bit down into
      // the arrow function's scope.
      scope->RecordEvalCall();

1408
      return Call::IS_POSSIBLY_EVAL;
1409
    }
1410
    return Call::NOT_EVAL;
1411 1412
  }

1413 1414
  // Convenience method which determines the type of return statement to emit
  // depending on the current function type.
1415 1416
  inline StatementT BuildReturnStatement(ExpressionT expr, int pos,
                                         int end_pos = kNoSourcePosition) {
1417
    if (impl()->IsNull(expr)) {
1418
      expr = factory()->NewUndefinedLiteral(kNoSourcePosition);
1419 1420 1421 1422
    } else if (is_async_generator()) {
      // In async generators, if there is an explicit operand to the return
      // statement, await the operand.
      expr = factory()->NewAwait(expr, kNoSourcePosition);
1423
      function_state_->AddSuspend();
1424 1425 1426 1427 1428
    }
    if (is_async_function()) {
      return factory()->NewAsyncReturnStatement(expr, pos, end_pos);
    }
    return factory()->NewReturnStatement(expr, pos, end_pos);
1429 1430
  }

1431
  // Validation per ES6 object literals.
1432
  class ObjectLiteralChecker {
1433 1434
   public:
    explicit ObjectLiteralChecker(ParserBase* parser)
1435
        : parser_(parser), has_seen_proto_(false) {}
1436

1437
    void CheckDuplicateProto(Token::Value property);
1438 1439

   private:
1440 1441 1442 1443
    bool IsProto() const {
      return this->scanner()->CurrentMatchesContextualEscaped(
          Token::PROTO_UNDERSCORED);
    }
1444

1445 1446 1447 1448
    ParserBase* parser() const { return parser_; }
    Scanner* scanner() const { return parser_->scanner(); }

    ParserBase* parser_;
1449 1450 1451 1452
    bool has_seen_proto_;
  };

  // Validation per ES6 class literals.
1453
  class ClassLiteralChecker {
1454 1455
   public:
    explicit ClassLiteralChecker(ParserBase* parser)
1456
        : parser_(parser), has_seen_constructor_(false) {}
1457

1458 1459 1460
    void CheckClassMethodName(Token::Value property, PropertyKind type,
                              bool is_generator, bool is_async, bool is_static,
                              bool* ok);
1461
    void CheckClassFieldName(bool is_static, bool* ok);
1462 1463 1464

   private:
    bool IsConstructor() {
1465 1466
      return this->scanner()->CurrentMatchesContextualEscaped(
          Token::CONSTRUCTOR);
1467
    }
1468 1469 1470 1471
    bool IsPrivateConstructor() {
      return this->scanner()->CurrentMatchesContextualEscaped(
          Token::PRIVATE_CONSTRUCTOR);
    }
1472
    bool IsPrototype() {
1473
      return this->scanner()->CurrentMatchesContextualEscaped(Token::PROTOTYPE);
1474 1475
    }

1476 1477 1478 1479
    ParserBase* parser() const { return parser_; }
    Scanner* scanner() const { return parser_->scanner(); }

    ParserBase* parser_;
1480 1481 1482
    bool has_seen_constructor_;
  };

1483
  ModuleDescriptor* module() const {
1484
    return scope()->AsModuleScope()->module();
1485
  }
1486
  Scope* scope() const { return scope_; }
1487

1488 1489 1490 1491 1492 1493 1494 1495 1496
  // Stack of expression classifiers.
  // The top of the stack is always pointed to by classifier().
  V8_INLINE ExpressionClassifier* classifier() const {
    DCHECK_NOT_NULL(classifier_);
    return classifier_;
  }

  // Accumulates the classifier that is on top of the stack (inner) to
  // the one that is right below (outer) and pops the inner.
1497
  V8_INLINE void Accumulate(unsigned productions) {
1498 1499 1500
    DCHECK_NOT_NULL(classifier_);
    ExpressionClassifier* previous = classifier_->previous();
    DCHECK_NOT_NULL(previous);
1501
    previous->Accumulate(classifier_, productions);
1502 1503 1504
    classifier_ = previous;
  }

1505 1506
  V8_INLINE void AccumulateNonBindingPatternErrors() {
    this->Accumulate(ExpressionClassifier::AllProductions &
1507 1508
                     ~(ExpressionClassifier::BindingPatternProduction |
                       ExpressionClassifier::LetPatternProduction));
1509 1510
  }

1511 1512
  // Pops and discards the classifier that is on top of the stack
  // without accumulating.
1513
  V8_INLINE void DiscardExpressionClassifier() {
1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533
    DCHECK_NOT_NULL(classifier_);
    classifier_->Discard();
    classifier_ = classifier_->previous();
  }

  // Accumulate errors that can be arbitrarily deep in an expression.
  // These correspond to the ECMAScript spec's 'Contains' operation
  // on productions. This includes:
  //
  // - YieldExpression is disallowed in arrow parameters in a generator.
  // - AwaitExpression is disallowed in arrow parameters in an async function.
  // - AwaitExpression is disallowed in async arrow parameters.
  //
  V8_INLINE void AccumulateFormalParameterContainmentErrors() {
    Accumulate(ExpressionClassifier::FormalParameterInitializerProduction |
               ExpressionClassifier::AsyncArrowFormalParametersProduction);
  }

  // Parser base's protected field members.

1534
  Scope* scope_;                   // Scope stack.
1535
  Scope* original_scope_;  // The top scope for the current parsing item.
1536 1537 1538 1539
  FunctionState* function_state_;  // Function state stack.
  v8::Extension* extension_;
  FuncNameInferrer* fni_;
  AstValueFactory* ast_value_factory_;  // Not owned.
1540
  typename Types::Factory ast_node_factory_;
1541
  RuntimeCallStats* runtime_call_stats_;
1542
  internal::Logger* logger_;
1543
  bool parsing_on_main_thread_;
1544
  const bool parsing_module_;
1545
  uintptr_t stack_limit_;
1546
  PendingCompilationErrorHandler* pending_error_handler_;
1547

1548 1549
  // Parser base's private field members.

1550 1551
 private:
  Zone* zone_;
1552
  ExpressionClassifier* classifier_;
1553 1554 1555

  Scanner* scanner_;

1556 1557
  FunctionLiteral::EagerCompileHint default_eager_compile_hint_;

1558
  int function_literal_id_;
1559
  int script_id_;
1560

1561 1562
  bool allow_natives_;
  bool allow_harmony_do_expressions_;
1563
  bool allow_harmony_public_fields_;
1564
  bool allow_harmony_static_fields_;
1565
  bool allow_harmony_dynamic_import_;
1566
  bool allow_harmony_import_meta_;
1567
  bool allow_harmony_private_fields_;
1568
  bool allow_eval_cache_;
1569 1570

  friend class DiscardableZoneScope;
1571 1572
};

1573 1574
template <typename Impl>
ParserBase<Impl>::FunctionState::FunctionState(
1575
    FunctionState** function_state_stack, Scope** scope_stack,
1576
    DeclarationScope* scope)
1577
    : BlockState(scope_stack, scope),
1578
      expected_property_count_(0),
1579
      suspend_count_(0),
1580 1581
      function_state_stack_(function_state_stack),
      outer_function_state_(*function_state_stack),
1582
      scope_(scope),
1583
      destructuring_assignments_to_rewrite_(scope->zone()),
1584
      reported_errors_(16, scope->zone()),
1585
      dont_optimize_reason_(BailoutReason::kNoReason),
1586
      next_function_is_likely_called_(false),
1587 1588
      previous_function_was_likely_called_(false),
      contains_function_or_eval_(false) {
1589
  *function_state_stack = this;
1590
  if (outer_function_state_) {
1591 1592
    outer_function_state_->previous_function_was_likely_called_ =
        outer_function_state_->next_function_is_likely_called_;
1593
    outer_function_state_->next_function_is_likely_called_ = false;
1594
  }
1595 1596
}

1597 1598
template <typename Impl>
ParserBase<Impl>::FunctionState::~FunctionState() {
1599 1600 1601
  *function_state_stack_ = outer_function_state_;
}

1602 1603
template <typename Impl>
void ParserBase<Impl>::GetUnexpectedTokenMessage(
1604 1605
    Token::Value token, MessageTemplate::Template* message,
    Scanner::Location* location, const char** arg,
1606
    MessageTemplate::Template default_) {
1607
  *arg = nullptr;
1608 1609 1610 1611 1612 1613
  switch (token) {
    case Token::EOS:
      *message = MessageTemplate::kUnexpectedEOS;
      break;
    case Token::SMI:
    case Token::NUMBER:
1614
    case Token::BIGINT:
1615 1616 1617 1618 1619
      *message = MessageTemplate::kUnexpectedTokenNumber;
      break;
    case Token::STRING:
      *message = MessageTemplate::kUnexpectedTokenString;
      break;
1620
    case Token::PRIVATE_NAME:
1621 1622 1623
    case Token::IDENTIFIER:
      *message = MessageTemplate::kUnexpectedTokenIdentifier;
      break;
1624 1625
    case Token::AWAIT:
    case Token::ENUM:
1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642
      *message = MessageTemplate::kUnexpectedReserved;
      break;
    case Token::LET:
    case Token::STATIC:
    case Token::YIELD:
    case Token::FUTURE_STRICT_RESERVED_WORD:
      *message = is_strict(language_mode())
                     ? MessageTemplate::kUnexpectedStrictReserved
                     : MessageTemplate::kUnexpectedTokenIdentifier;
      break;
    case Token::TEMPLATE_SPAN:
    case Token::TEMPLATE_TAIL:
      *message = MessageTemplate::kUnexpectedTemplateString;
      break;
    case Token::ESCAPED_STRICT_RESERVED_WORD:
    case Token::ESCAPED_KEYWORD:
      *message = MessageTemplate::kInvalidEscapedReservedWord;
1643 1644
      break;
    case Token::ILLEGAL:
1645 1646 1647 1648 1649 1650
      if (scanner()->has_error()) {
        *message = scanner()->error();
        *location = scanner()->error_location();
      } else {
        *message = MessageTemplate::kInvalidOrUnexpectedToken;
      }
1651
      break;
1652 1653 1654
    case Token::REGEXP_LITERAL:
      *message = MessageTemplate::kUnexpectedTokenRegExp;
      break;
1655 1656
    default:
      const char* name = Token::String(token);
1657
      DCHECK_NOT_NULL(name);
1658 1659 1660 1661 1662
      *arg = name;
      break;
  }
}

1663 1664
template <typename Impl>
void ParserBase<Impl>::ReportUnexpectedToken(Token::Value token) {
1665 1666 1667
  return ReportUnexpectedTokenAt(scanner_->location(), token);
}

1668 1669
template <typename Impl>
void ParserBase<Impl>::ReportUnexpectedTokenAt(
1670 1671 1672
    Scanner::Location source_location, Token::Value token,
    MessageTemplate::Template message) {
  const char* arg;
1673
  GetUnexpectedTokenMessage(token, &message, &source_location, &arg);
1674
  impl()->ReportMessageAt(source_location, message, arg);
1675 1676
}

1677 1678
template <typename Impl>
typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifier(
1679
    AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) {
1680
  ExpressionClassifier classifier(this);
1681
  auto result = ParseAndClassifyIdentifier(CHECK_OK_CUSTOM(NullIdentifier));
1682 1683

  if (allow_restricted_identifiers == kDontAllowRestrictedIdentifiers) {
1684 1685
    ValidateAssignmentPattern(CHECK_OK_CUSTOM(NullIdentifier));
    ValidateBindingPattern(CHECK_OK_CUSTOM(NullIdentifier));
1686 1687 1688 1689 1690
  }

  return result;
}

1691 1692
template <typename Impl>
typename ParserBase<Impl>::IdentifierT
1693
ParserBase<Impl>::ParseAndClassifyIdentifier(bool* ok) {
1694
  Token::Value next = Next();
1695
  if (next == Token::IDENTIFIER || next == Token::ASYNC ||
1696
      (next == Token::AWAIT && !parsing_module_ && !is_async_function())) {
1697
    IdentifierT name = impl()->GetSymbol();
1698 1699 1700 1701 1702 1703 1704

    if (impl()->IsArguments(name) && scope()->ShouldBanArguments()) {
      ReportMessage(MessageTemplate::kArgumentsDisallowedInInitializer);
      *ok = false;
      return impl()->NullIdentifier();
    }

1705 1706 1707 1708 1709 1710
    // 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
    // arrow functions we don't always know that the identifier we are reading
    // is actually a formal parameter.  Therefore besides the errors that we
    // must detect because we know we're in strict mode, we also record any
    // error that we might make in the future once we know the language mode.
1711
    if (impl()->IsEvalOrArguments(name)) {
1712
      classifier()->RecordStrictModeFormalParameterError(
1713 1714
          scanner()->location(), MessageTemplate::kStrictEvalArguments);
      if (is_strict(language_mode())) {
1715
        classifier()->RecordBindingPatternError(
1716 1717
            scanner()->location(), MessageTemplate::kStrictEvalArguments);
      }
1718
    } else if (next == Token::AWAIT) {
1719
      classifier()->RecordAsyncArrowFormalParametersError(
1720 1721
          scanner()->location(), MessageTemplate::kAwaitBindingIdentifier);
    }
1722

1723
    if (classifier()->duplicate_finder() != nullptr &&
1724 1725
        scanner()->IsDuplicateSymbol(classifier()->duplicate_finder(),
                                     ast_value_factory())) {
1726
      classifier()->RecordDuplicateFormalParameterError(scanner()->location());
1727 1728 1729 1730 1731 1732 1733
    }
    return name;
  } else if (is_sloppy(language_mode()) &&
             (next == Token::FUTURE_STRICT_RESERVED_WORD ||
              next == Token::ESCAPED_STRICT_RESERVED_WORD ||
              next == Token::LET || next == Token::STATIC ||
              (next == Token::YIELD && !is_generator()))) {
1734
    classifier()->RecordStrictModeFormalParameterError(
1735 1736 1737 1738 1739
        scanner()->location(), MessageTemplate::kUnexpectedStrictReserved);
    if (next == Token::ESCAPED_STRICT_RESERVED_WORD &&
        is_strict(language_mode())) {
      ReportUnexpectedToken(next);
      *ok = false;
1740
      return impl()->NullIdentifier();
1741
    }
1742
    if (scanner()->IsLet()) {
1743 1744
      classifier()->RecordLetPatternError(
          scanner()->location(), MessageTemplate::kLetInLexicalBinding);
1745
    }
1746
    return impl()->GetSymbol();
1747
  } else {
1748
    ReportUnexpectedToken(next);
1749
    *ok = false;
1750
    return impl()->NullIdentifier();
1751 1752 1753
  }
}

1754 1755 1756
template <class Impl>
typename ParserBase<Impl>::IdentifierT
ParserBase<Impl>::ParseIdentifierOrStrictReservedWord(
1757 1758
    FunctionKind function_kind, bool* is_strict_reserved, bool* is_await,
    bool* ok) {
1759
  Token::Value next = Next();
1760 1761
  if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_ &&
                                    !IsAsyncFunction(function_kind)) ||
1762
      next == Token::ASYNC) {
1763
    *is_strict_reserved = false;
1764
    *is_await = next == Token::AWAIT;
1765 1766
  } else if (next == Token::ESCAPED_STRICT_RESERVED_WORD ||
             next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
1767 1768
             next == Token::STATIC ||
             (next == Token::YIELD && !IsGeneratorFunction(function_kind))) {
1769 1770 1771 1772
    *is_strict_reserved = true;
  } else {
    ReportUnexpectedToken(next);
    *ok = false;
1773
    return impl()->NullIdentifier();
1774 1775
  }

1776
  return impl()->GetSymbol();
1777 1778
}

1779 1780 1781
template <typename Impl>
typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifierName(
    bool* ok) {
1782
  Token::Value next = Next();
1783 1784 1785 1786
  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 &&
1787 1788
      next != Token::ESCAPED_KEYWORD &&
      next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) {
1789
    ReportUnexpectedToken(next);
1790
    *ok = false;
1791
    return impl()->NullIdentifier();
1792 1793
  }

1794
  return impl()->GetSymbol();
1795 1796
}

1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseIdentifierNameOrPrivateName(bool* ok) {
  int pos = position();
  IdentifierT name;
  ExpressionT key;
  if (allow_harmony_private_fields() && peek() == Token::PRIVATE_NAME) {
    Consume(Token::PRIVATE_NAME);
    name = impl()->GetSymbol();
    auto key_proxy =
        impl()->ExpressionFromIdentifier(name, pos, InferName::kNo);
    key_proxy->set_is_private_field();
    key = key_proxy;
  } else {
    name = ParseIdentifierName(CHECK_OK);
    key = factory()->NewStringLiteral(name, pos);
  }
  impl()->PushLiteralName(name);
  return key;
}

1818 1819
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseRegExpLiteral(
1820
    bool* ok) {
1821
  int pos = peek_position();
1822
  if (!scanner()->ScanRegExpPattern()) {
1823 1824 1825
    Next();
    ReportMessage(MessageTemplate::kUnterminatedRegExp);
    *ok = false;
1826
    return impl()->NullExpression();
1827 1828
  }

1829
  IdentifierT js_pattern = impl()->GetNextSymbol();
1830 1831 1832 1833 1834
  Maybe<RegExp::Flags> flags = scanner()->ScanRegExpFlags();
  if (flags.IsNothing()) {
    Next();
    ReportMessage(MessageTemplate::kMalformedRegExpFlags);
    *ok = false;
1835
    return impl()->NullExpression();
1836 1837 1838
  }
  int js_flags = flags.FromJust();
  Next();
1839
  return factory()->NewRegExpLiteral(js_pattern, js_flags, pos);
1840 1841
}

1842 1843
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePrimaryExpression(
1844
    bool* is_async, bool* ok) {
1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859
  // PrimaryExpression ::
  //   'this'
  //   'null'
  //   'true'
  //   'false'
  //   Identifier
  //   Number
  //   String
  //   ArrayLiteral
  //   ObjectLiteral
  //   RegExpLiteral
  //   ClassLiteral
  //   '(' Expression ')'
  //   TemplateLiteral
  //   do Block
1860
  //   AsyncFunctionLiteral
1861 1862 1863 1864

  int beg_pos = peek_position();
  switch (peek()) {
    case Token::THIS: {
1865
      BindingPatternUnexpectedToken();
1866
      Consume(Token::THIS);
1867
      return impl()->ThisExpression(beg_pos);
1868 1869 1870 1871 1872 1873 1874
    }

    case Token::NULL_LITERAL:
    case Token::TRUE_LITERAL:
    case Token::FALSE_LITERAL:
    case Token::SMI:
    case Token::NUMBER:
1875
    case Token::BIGINT:
1876
      BindingPatternUnexpectedToken();
1877
      return impl()->ExpressionFromLiteral(Next(), beg_pos);
1878

1879
    case Token::ASYNC:
1880
      if (!scanner()->HasLineTerminatorAfterNext() &&
1881
          PeekAhead() == Token::FUNCTION) {
1882
        BindingPatternUnexpectedToken();
1883
        Consume(Token::ASYNC);
1884
        return ParseAsyncFunctionLiteral(CHECK_OK);
1885 1886 1887
      }
      // CoverCallExpressionAndAsyncArrowHead
      *is_async = true;
1888
      V8_FALLTHROUGH;
1889 1890 1891 1892
    case Token::IDENTIFIER:
    case Token::LET:
    case Token::STATIC:
    case Token::YIELD:
1893
    case Token::AWAIT:
1894 1895 1896
    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.
1897
      IdentifierT name = ParseAndClassifyIdentifier(CHECK_OK);
1898
      return impl()->ExpressionFromIdentifier(name, beg_pos);
1899 1900 1901
    }

    case Token::STRING: {
1902
      BindingPatternUnexpectedToken();
1903
      Consume(Token::STRING);
1904
      return impl()->ExpressionFromString(beg_pos);
1905 1906 1907 1908
    }

    case Token::ASSIGN_DIV:
    case Token::DIV:
1909
      classifier()->RecordBindingPatternError(
1910
          scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp);
1911
      return ParseRegExpLiteral(ok);
1912 1913

    case Token::LBRACK:
1914
      return ParseArrayLiteral(ok);
1915 1916

    case Token::LBRACE:
1917
      return ParseObjectLiteral(ok);
1918 1919 1920 1921 1922 1923 1924

    case Token::LPAREN: {
      // Arrow function formal parameters are either a single identifier or a
      // list of BindingPattern productions enclosed in parentheses.
      // Parentheses are not valid on the LHS of a BindingPattern, so we use the
      // is_valid_binding_pattern() check to detect multiple levels of
      // parenthesization.
1925 1926 1927 1928 1929
      bool pattern_error = !classifier()->is_valid_binding_pattern();
      classifier()->RecordPatternError(scanner()->peek_location(),
                                       MessageTemplate::kUnexpectedToken,
                                       Token::String(Token::LPAREN));
      if (pattern_error) ArrowFormalParametersUnexpectedToken();
1930 1931 1932 1933
      Consume(Token::LPAREN);
      if (Check(Token::RPAREN)) {
        // ()=>x.  The continuation that looks for the => is in
        // ParseAssignmentExpression.
1934 1935 1936
        classifier()->RecordExpressionError(scanner()->location(),
                                            MessageTemplate::kUnexpectedToken,
                                            Token::String(Token::RPAREN));
1937 1938 1939 1940
        return factory()->NewEmptyParentheses(beg_pos);
      }
      // Heuristically try to detect immediately called functions before
      // seeing the call parentheses.
1941 1942
      if (peek() == Token::FUNCTION ||
          (peek() == Token::ASYNC && PeekAhead() == Token::FUNCTION)) {
1943 1944
        function_state_->set_next_function_is_likely_called();
      }
1945
      ExpressionT expr = ParseExpressionCoverGrammar(true, CHECK_OK);
1946 1947 1948 1949 1950
      Expect(Token::RPAREN, CHECK_OK);
      return expr;
    }

    case Token::CLASS: {
1951
      BindingPatternUnexpectedToken();
1952
      Consume(Token::CLASS);
1953
      int class_token_pos = position();
1954
      IdentifierT name = impl()->NullIdentifier();
1955 1956 1957
      bool is_strict_reserved_name = false;
      Scanner::Location class_name_location = Scanner::Location::invalid();
      if (peek_any_identifier()) {
1958
        bool is_await = false;
1959
        name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
1960
                                                   &is_await, CHECK_OK);
1961
        class_name_location = scanner()->location();
1962 1963 1964 1965
        if (is_await) {
          classifier()->RecordAsyncArrowFormalParametersError(
              scanner()->location(), MessageTemplate::kAwaitBindingIdentifier);
        }
1966
      }
1967 1968
      return ParseClassLiteral(name, class_name_location,
                               is_strict_reserved_name, class_token_pos, ok);
1969 1970 1971 1972
    }

    case Token::TEMPLATE_SPAN:
    case Token::TEMPLATE_TAIL:
1973
      BindingPatternUnexpectedToken();
1974
      return ParseTemplateLiteral(impl()->NullExpression(), beg_pos, false, ok);
1975 1976

    case Token::MOD:
1977
      if (allow_natives() || extension_ != nullptr) {
1978
        BindingPatternUnexpectedToken();
1979
        return ParseV8Intrinsic(ok);
1980 1981 1982 1983 1984
      }
      break;

    case Token::DO:
      if (allow_harmony_do_expressions()) {
1985
        BindingPatternUnexpectedToken();
1986
        return ParseDoExpression(ok);
1987 1988 1989 1990 1991 1992 1993 1994 1995
      }
      break;

    default:
      break;
  }

  ReportUnexpectedToken(Next());
  *ok = false;
1996
  return impl()->NullExpression();
1997 1998
}

1999 2000
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression(
2001
    bool accept_IN, bool* ok) {
2002
  ExpressionClassifier classifier(this);
2003
  ExpressionT result = ParseExpressionCoverGrammar(accept_IN, CHECK_OK);
2004
  ValidateExpression(CHECK_OK);
2005 2006 2007
  return result;
}

2008
template <typename Impl>
2009 2010
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseExpressionCoverGrammar(bool accept_IN, bool* ok) {
2011 2012 2013 2014
  // Expression ::
  //   AssignmentExpression
  //   Expression ',' AssignmentExpression

2015
  ExpressionT result = impl()->NullExpression();
2016 2017 2018 2019 2020 2021 2022 2023
  while (true) {
    int comma_pos = position();
    ExpressionClassifier binding_classifier(this);
    ExpressionT right;
    if (Check(Token::ELLIPSIS)) {
      // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only
      // as the formal parameters of'(x, y, ...z) => foo', and is not itself a
      // valid expression.
2024 2025 2026
      classifier()->RecordExpressionError(scanner()->location(),
                                          MessageTemplate::kUnexpectedToken,
                                          Token::String(Token::ELLIPSIS));
2027 2028
      int ellipsis_pos = position();
      int pattern_pos = peek_position();
2029
      ExpressionT pattern = ParsePrimaryExpression(CHECK_OK);
2030 2031 2032 2033 2034
      if (peek() == Token::ASSIGN) {
        ReportMessage(MessageTemplate::kRestDefaultInitializer);
        *ok = false;
        return result;
      }
2035
      ValidateBindingPattern(CHECK_OK);
2036 2037
      right = factory()->NewSpread(pattern, ellipsis_pos, pattern_pos);
    } else {
2038
      right = ParseAssignmentExpression(accept_IN, CHECK_OK);
2039 2040 2041
    }
    // No need to accumulate binding pattern-related errors, since
    // an Expression can't be a binding pattern anyway.
2042
    AccumulateNonBindingPatternErrors();
2043
    if (!impl()->IsIdentifier(right)) classifier()->RecordNonSimpleParameter();
2044
    if (impl()->IsNull(result)) {
2045 2046
      // First time through the loop.
      result = right;
2047
    } else if (impl()->CollapseNaryExpression(&result, right, Token::COMMA,
2048 2049
                                              comma_pos,
                                              SourceRange::Empty())) {
2050
      // Do nothing, "result" is already updated.
2051 2052 2053 2054 2055 2056 2057 2058
    } else {
      result =
          factory()->NewBinaryOperation(Token::COMMA, result, right, comma_pos);
    }

    if (!Check(Token::COMMA)) break;

    if (right->IsSpread()) {
2059
      classifier()->RecordArrowFormalParametersError(
2060
          scanner()->location(), MessageTemplate::kParamAfterRest);
2061
    }
2062

2063
    if (peek() == Token::RPAREN && PeekAhead() == Token::ARROW) {
2064 2065
      // a trailing comma is allowed at the end of an arrow parameter list
      break;
2066
    }
2067 2068 2069 2070 2071 2072 2073

    // Pass on the 'set_next_function_is_likely_called' flag if we have
    // several function literals separated by comma.
    if (peek() == Token::FUNCTION &&
        function_state_->previous_function_was_likely_called()) {
      function_state_->set_next_function_is_likely_called();
    }
2074 2075 2076 2077 2078
  }

  return result;
}

2079 2080
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseArrayLiteral(
2081
    bool* ok) {
2082 2083 2084 2085
  // ArrayLiteral ::
  //   '[' Expression? (',' Expression?)* ']'

  int pos = peek_position();
2086
  ExpressionListT values = impl()->NewExpressionList(4);
2087
  int first_spread_index = -1;
2088
  Consume(Token::LBRACK);
2089
  while (peek() != Token::RBRACK) {
2090
    ExpressionT elem;
2091
    if (peek() == Token::COMMA) {
2092
      elem = factory()->NewTheHoleLiteral();
2093 2094 2095
    } else if (peek() == Token::ELLIPSIS) {
      int start_pos = peek_position();
      Consume(Token::ELLIPSIS);
nikolaos's avatar
nikolaos committed
2096
      int expr_pos = peek_position();
2097
      ExpressionT argument = ParseAssignmentExpression(true, CHECK_OK);
nikolaos's avatar
nikolaos committed
2098
      elem = factory()->NewSpread(argument, start_pos, expr_pos);
2099 2100 2101 2102 2103

      if (first_spread_index < 0) {
        first_spread_index = values->length();
      }

2104
      if (argument->IsAssignment()) {
2105
        classifier()->RecordPatternError(
2106 2107 2108
            Scanner::Location(start_pos, scanner()->location().end_pos),
            MessageTemplate::kInvalidDestructuringTarget);
      } else {
2109
        CheckDestructuringElement(argument, start_pos,
2110 2111
                                  scanner()->location().end_pos);
      }
2112 2113

      if (peek() == Token::COMMA) {
2114
        classifier()->RecordPatternError(
2115 2116 2117 2118
            Scanner::Location(start_pos, scanner()->location().end_pos),
            MessageTemplate::kElementAfterRest);
      }
    } else {
2119
      int beg_pos = peek_position();
2120 2121
      elem = ParseAssignmentExpression(true, CHECK_OK);
      CheckDestructuringElement(elem, beg_pos, scanner()->location().end_pos);
2122 2123 2124 2125 2126 2127 2128 2129
    }
    values->Add(elem, zone_);
    if (peek() != Token::RBRACK) {
      Expect(Token::COMMA, CHECK_OK);
    }
  }
  Expect(Token::RBRACK, CHECK_OK);

2130
  return factory()->NewArrayLiteral(values, first_spread_index, pos);
2131 2132
}

2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150
template <class Impl>
bool ParserBase<Impl>::SetPropertyKindFromToken(Token::Value token,
                                                PropertyKind* kind) {
  // This returns true, setting the property kind, iff the given token is one
  // which must occur after a property name, indicating that the previous token
  // was in fact a name and not a modifier (like the "get" in "get x").
  switch (token) {
    case Token::COLON:
      *kind = PropertyKind::kValueProperty;
      return true;
    case Token::COMMA:
    case Token::RBRACE:
    case Token::ASSIGN:
      *kind = PropertyKind::kShorthandProperty;
      return true;
    case Token::LPAREN:
      *kind = PropertyKind::kMethodProperty;
      return true;
2151 2152 2153 2154
    case Token::MUL:
    case Token::SEMICOLON:
      *kind = PropertyKind::kClassField;
      return true;
2155 2156 2157
    case Token::PRIVATE_NAME:
      *kind = PropertyKind::kClassField;
      return true;
2158 2159 2160 2161 2162 2163
    default:
      break;
  }
  return false;
}

2164 2165
template <class Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName(
2166 2167
    IdentifierT* name, PropertyKind* kind, bool* is_generator, bool* is_async,
    bool* is_computed_name, bool* ok) {
2168
  DCHECK_EQ(*kind, PropertyKind::kNotSet);
2169 2170 2171 2172 2173 2174 2175 2176 2177
  DCHECK(!*is_generator);
  DCHECK(!*is_async);
  DCHECK(!*is_computed_name);

  *is_generator = Check(Token::MUL);
  if (*is_generator) {
    *kind = PropertyKind::kMethodProperty;
  }

2178 2179 2180
  Token::Value token = peek();
  int pos = peek_position();

2181
  if (!*is_generator && token == Token::ASYNC &&
2182
      !scanner()->HasLineTerminatorAfterNext()) {
2183 2184
    Consume(Token::ASYNC);
    token = peek();
2185
    if (token == Token::MUL && !scanner()->HasLineTerminatorBeforeNext()) {
2186 2187 2188 2189
      Consume(Token::MUL);
      token = peek();
      *is_generator = true;
    } else if (SetPropertyKindFromToken(token, kind)) {
2190
      *name = impl()->GetSymbol();  // TODO(bakkot) specialize on 'async'
2191
      impl()->PushLiteralName(*name);
2192 2193 2194 2195 2196 2197 2198 2199
      return factory()->NewStringLiteral(*name, pos);
    }
    *kind = PropertyKind::kMethodProperty;
    *is_async = true;
    pos = peek_position();
  }

  if (token == Token::IDENTIFIER && !*is_generator && !*is_async) {
2200
    // This is checking for 'get' and 'set' in particular.
2201 2202
    Consume(Token::IDENTIFIER);
    token = peek();
2203 2204 2205 2206 2207 2208 2209 2210 2211 2212
    bool previous_token_was_name = SetPropertyKindFromToken(token, kind);
    Token::Value contextual_token = scanner()->current_contextual_token();
    if (!previous_token_was_name && Token::IsGetOrSet(contextual_token)) {
      if (contextual_token == Token::GET) {
        *kind = PropertyKind::kAccessorGetterProperty;
      } else {
        *kind = PropertyKind::kAccessorSetterProperty;
      }
      pos = peek_position();
    } else {
2213
      *name = impl()->GetSymbol();
2214
      impl()->PushLiteralName(*name);
2215 2216 2217 2218
      return factory()->NewStringLiteral(*name, pos);
    }
  }

2219 2220 2221 2222 2223 2224 2225 2226 2227
  // For non computed property names we normalize the name a bit:
  //
  //   "12" -> 12
  //   12.3 -> "12.3"
  //   12.30 -> "12.3"
  //   identifier -> "identifier"
  //
  // This is important because we use the property name as a key in a hash
  // table when we compute constant properties.
2228
  ExpressionT expression = impl()->NullExpression();
2229 2230 2231
  switch (token) {
    case Token::STRING:
      Consume(Token::STRING);
2232
      *name = impl()->GetSymbol();
2233 2234 2235 2236
      break;

    case Token::SMI:
      Consume(Token::SMI);
2237
      *name = impl()->GetNumberAsSymbol();
2238 2239 2240 2241
      break;

    case Token::NUMBER:
      Consume(Token::NUMBER);
2242
      *name = impl()->GetNumberAsSymbol();
2243 2244 2245
      break;

    case Token::LBRACK: {
2246
      *name = impl()->NullIdentifier();
2247 2248
      *is_computed_name = true;
      Consume(Token::LBRACK);
2249
      ExpressionClassifier computed_name_classifier(this);
2250
      expression = ParseAssignmentExpression(true, CHECK_OK);
2251
      ValidateExpression(CHECK_OK);
2252
      AccumulateFormalParameterContainmentErrors();
2253
      Expect(Token::RBRACK, CHECK_OK);
2254
      break;
2255 2256
    }

2257
    case Token::ELLIPSIS:
2258
      if (!*is_generator && !*is_async && !IsAccessor(*kind)) {
2259
        *name = impl()->NullIdentifier();
2260 2261 2262
        Consume(Token::ELLIPSIS);
        expression = ParseAssignmentExpression(true, CHECK_OK);
        *kind = PropertyKind::kSpreadProperty;
2263

2264 2265
        if (!impl()->IsIdentifier(expression)) {
          classifier()->RecordBindingPatternError(
2266
              scanner()->location(),
2267 2268 2269 2270 2271 2272 2273
              MessageTemplate::kInvalidRestBindingPattern);
        }

        if (!expression->IsValidReferenceExpression()) {
          classifier()->RecordAssignmentPatternError(
              scanner()->location(),
              MessageTemplate::kInvalidRestAssignmentPattern);
2274 2275 2276 2277 2278 2279
        }

        if (peek() != Token::RBRACE) {
          classifier()->RecordPatternError(scanner()->location(),
                                           MessageTemplate::kElementAfterRest);
        }
2280 2281
        return expression;
      }
2282
      V8_FALLTHROUGH;
2283

2284
    default:
2285
      *name = ParseIdentifierName(CHECK_OK);
2286 2287 2288
      break;
  }

2289
  if (*kind == PropertyKind::kNotSet) {
2290
    SetPropertyKindFromToken(peek(), kind);
2291 2292 2293 2294 2295 2296
  }

  if (*is_computed_name) {
    return expression;
  }

2297
  impl()->PushLiteralName(*name);
2298

2299
  uint32_t index;
2300
  return impl()->IsArrayIndex(*name, &index)
2301 2302 2303 2304
             ? factory()->NewNumberLiteral(index, pos)
             : factory()->NewStringLiteral(*name, pos);
}

2305
template <typename Impl>
2306
typename ParserBase<Impl>::ClassLiteralPropertyT
2307
ParserBase<Impl>::ParseClassPropertyDefinition(
2308
    ClassLiteralChecker* checker, ClassInfo* class_info, IdentifierT* name,
2309 2310 2311
    bool has_extends, bool* is_computed_name,
    ClassLiteralProperty::Kind* property_kind, bool* is_static, bool* ok) {
  DCHECK_NOT_NULL(class_info);
2312
  bool is_generator = false;
2313
  bool is_async = false;
2314 2315
  *is_static = false;
  *property_kind = ClassLiteralProperty::METHOD;
2316
  PropertyKind kind = PropertyKind::kNotSet;
2317

2318
  Token::Value name_token = peek();
2319 2320
  DCHECK_IMPLIES(name_token == Token::PRIVATE_NAME,
                 allow_harmony_private_fields());
2321

2322
  int name_token_position = scanner()->peek_location().beg_pos;
2323
  *name = impl()->NullIdentifier();
2324 2325 2326
  ExpressionT name_expression;
  if (name_token == Token::STATIC) {
    Consume(Token::STATIC);
2327
    name_token_position = scanner()->peek_location().beg_pos;
2328 2329
    if (peek() == Token::LPAREN) {
      kind = PropertyKind::kMethodProperty;
2330 2331
      *name = impl()->GetSymbol();  // TODO(bakkot) specialize on 'static'
      name_expression = factory()->NewStringLiteral(*name, position());
2332 2333
    } else if (peek() == Token::ASSIGN || peek() == Token::SEMICOLON ||
               peek() == Token::RBRACE) {
2334 2335
      *name = impl()->GetSymbol();  // TODO(bakkot) specialize on 'static'
      name_expression = factory()->NewStringLiteral(*name, position());
2336 2337 2338 2339 2340 2341
    } else if (peek() == Token::PRIVATE_NAME) {
      DCHECK(allow_harmony_private_fields());
      // TODO(gsathya): Make a better error message for this.
      ReportUnexpectedToken(Next());
      *ok = false;
      return impl()->NullLiteralProperty();
2342
    } else {
2343
      *is_static = true;
2344 2345
      name_expression = ParsePropertyName(name, &kind, &is_generator, &is_async,
                                          is_computed_name,
2346
                                          CHECK_OK_CUSTOM(NullLiteralProperty));
2347
    }
2348 2349
  } else if (name_token == Token::PRIVATE_NAME) {
    Consume(Token::PRIVATE_NAME);
2350 2351
    *name = impl()->GetSymbol();
    name_expression = factory()->NewStringLiteral(*name, position());
2352
  } else {
2353 2354
    name_expression = ParsePropertyName(name, &kind, &is_generator, &is_async,
                                        is_computed_name,
2355
                                        CHECK_OK_CUSTOM(NullLiteralProperty));
2356 2357
  }

2358 2359 2360
  if (!class_info->has_name_static_property && *is_static &&
      impl()->IsName(*name)) {
    class_info->has_name_static_property = true;
2361 2362
  }

2363
  switch (kind) {
2364 2365 2366 2367 2368 2369 2370 2371
    case PropertyKind::kClassField:
    case PropertyKind::kNotSet:  // This case is a name followed by a name or
                                 // other property. Here we have to assume
                                 // that's an uninitialized field followed by a
                                 // linebreak followed by a property, with ASI
                                 // adding the semicolon. If not, there will be
                                 // a syntax error after parsing the first name
                                 // as an uninitialized field.
2372 2373
    case PropertyKind::kShorthandProperty:
    case PropertyKind::kValueProperty:
2374
      if (allow_harmony_public_fields() || allow_harmony_private_fields()) {
2375 2376 2377
        *property_kind = name_token == Token::PRIVATE_NAME
                             ? ClassLiteralProperty::PRIVATE_FIELD
                             : ClassLiteralProperty::PUBLIC_FIELD;
2378 2379 2380 2381 2382
        if (*is_static && !allow_harmony_static_fields()) {
          ReportUnexpectedToken(Next());
          *ok = false;
          return impl()->NullLiteralProperty();
        }
2383
        if (!*is_computed_name) {
2384 2385 2386
          checker->CheckClassFieldName(*is_static,
                                       CHECK_OK_CUSTOM(NullLiteralProperty));
        }
2387 2388 2389
        ExpressionT initializer = ParseClassFieldInitializer(
            class_info, *is_static, CHECK_OK_CUSTOM(NullLiteralProperty));
        ExpectSemicolon(CHECK_OK_CUSTOM(NullLiteralProperty));
2390
        ClassLiteralPropertyT result = factory()->NewClassLiteralProperty(
2391
            name_expression, initializer, *property_kind, *is_static,
2392
            *is_computed_name);
2393
        impl()->SetFunctionNameFromPropertyName(result, *name);
2394 2395
        return result;

2396 2397 2398
      } else {
        ReportUnexpectedToken(Next());
        *ok = false;
2399
        return impl()->NullLiteralProperty();
2400
      }
2401 2402 2403 2404 2405

    case PropertyKind::kMethodProperty: {
      // MethodDefinition
      //    PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
      //    '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2406 2407 2408 2409
      //    async PropertyName '(' StrictFormalParameters ')'
      //        '{' FunctionBody '}'
      //    async '*' PropertyName '(' StrictFormalParameters ')'
      //        '{' FunctionBody '}'
2410 2411

      if (!*is_computed_name) {
2412 2413 2414
        checker->CheckClassMethodName(name_token, PropertyKind::kMethodProperty,
                                      is_generator, is_async, *is_static,
                                      CHECK_OK_CUSTOM(NullLiteralProperty));
2415 2416
      }

2417
      FunctionKind kind = MethodKindFor(is_generator, is_async);
2418

2419
      if (!*is_static && impl()->IsConstructor(*name)) {
2420
        class_info->has_seen_constructor = true;
2421
        kind = has_extends ? FunctionKind::kDerivedConstructor
2422 2423 2424 2425
                           : FunctionKind::kBaseConstructor;
      }

      ExpressionT value = impl()->ParseFunctionLiteral(
2426
          *name, scanner()->location(), kSkipFunctionNameCheck, kind,
2427
          FLAG_harmony_function_tostring ? name_token_position
2428
                                         : kNoSourcePosition,
2429
          FunctionLiteral::kAccessorOrMethod, language_mode(), nullptr,
2430
          CHECK_OK_CUSTOM(NullLiteralProperty));
2431

2432
      *property_kind = ClassLiteralProperty::METHOD;
2433 2434 2435
      ClassLiteralPropertyT result = factory()->NewClassLiteralProperty(
          name_expression, value, *property_kind, *is_static,
          *is_computed_name);
2436
      impl()->SetFunctionNameFromPropertyName(result, *name);
2437
      return result;
2438 2439
    }

2440 2441 2442 2443
    case PropertyKind::kAccessorGetterProperty:
    case PropertyKind::kAccessorSetterProperty: {
      DCHECK(!is_generator && !is_async);
      bool is_get = kind == PropertyKind::kAccessorGetterProperty;
2444 2445

      if (!*is_computed_name) {
2446 2447 2448
        checker->CheckClassMethodName(name_token, kind, false, false,
                                      *is_static,
                                      CHECK_OK_CUSTOM(NullLiteralProperty));
2449 2450 2451 2452
        // Make sure the name expression is a string since we need a Name for
        // Runtime_DefineAccessorPropertyUnchecked and since we can determine
        // this statically we can skip the extra runtime check.
        name_expression =
2453
            factory()->NewStringLiteral(*name, name_expression->position());
2454 2455 2456 2457 2458
      }

      FunctionKind kind = is_get ? FunctionKind::kGetterFunction
                                 : FunctionKind::kSetterFunction;

2459
      FunctionLiteralT value = impl()->ParseFunctionLiteral(
2460
          *name, scanner()->location(), kSkipFunctionNameCheck, kind,
2461
          FLAG_harmony_function_tostring ? name_token_position
2462
                                         : kNoSourcePosition,
2463
          FunctionLiteral::kAccessorOrMethod, language_mode(), nullptr,
2464
          CHECK_OK_CUSTOM(NullLiteralProperty));
2465

2466 2467
      *property_kind =
          is_get ? ClassLiteralProperty::GETTER : ClassLiteralProperty::SETTER;
2468 2469 2470 2471 2472 2473
      ClassLiteralPropertyT result = factory()->NewClassLiteralProperty(
          name_expression, value, *property_kind, *is_static,
          *is_computed_name);
      const AstRawString* prefix =
          is_get ? ast_value_factory()->get_space_string()
                 : ast_value_factory()->set_space_string();
2474
      impl()->SetFunctionNameFromPropertyName(result, *name, prefix);
2475
      return result;
2476
    }
2477
    case PropertyKind::kSpreadProperty:
2478 2479 2480 2481
      ReportUnexpectedTokenAt(
          Scanner::Location(name_token_position, name_expression->position()),
          name_token);
      *ok = false;
2482
      return impl()->NullLiteralProperty();
2483 2484 2485 2486
  }
  UNREACHABLE();
}

2487
template <typename Impl>
2488 2489 2490 2491 2492 2493 2494 2495
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseClassFieldInitializer(ClassInfo* class_info,
                                             bool is_static, bool* ok) {
  DeclarationScope* initializer_scope = is_static
                                            ? class_info->static_fields_scope
                                            : class_info->instance_fields_scope;

  if (initializer_scope == nullptr) {
2496 2497
    initializer_scope =
        NewFunctionScope(FunctionKind::kClassFieldsInitializerFunction);
2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510
    // TODO(gsathya): Make scopes be non contiguous.
    initializer_scope->set_start_position(scanner()->location().end_pos);
    initializer_scope->SetLanguageMode(LanguageMode::kStrict);
  }

  ExpressionT initializer;
  if (Check(Token::ASSIGN)) {
    FunctionState initializer_state(&function_state_, &scope_,
                                    initializer_scope);
    ExpressionClassifier expression_classifier(this);

    initializer =
        ParseAssignmentExpression(true, CHECK_OK_CUSTOM(NullExpression));
2511
    ValidateExpression(CHECK_OK_CUSTOM(NullExpression));
2512
  } else {
2513
    initializer = factory()->NewUndefinedLiteral(kNoSourcePosition);
2514
  }
2515

2516
  initializer_scope->set_end_position(scanner()->location().end_pos);
2517 2518 2519 2520 2521 2522 2523 2524 2525
  if (is_static) {
    class_info->static_fields_scope = initializer_scope;
    class_info->has_static_class_fields = true;
  } else {
    class_info->instance_fields_scope = initializer_scope;
    class_info->has_instance_class_fields = true;
  }

  return initializer;
2526 2527
}

2528 2529 2530 2531
template <typename Impl>
typename ParserBase<Impl>::ObjectLiteralPropertyT
ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker,
                                                bool* is_computed_name,
2532
                                                bool* is_rest_property,
2533
                                                bool* ok) {
2534 2535 2536 2537
  bool is_generator = false;
  bool is_async = false;
  PropertyKind kind = PropertyKind::kNotSet;

2538
  IdentifierT name = impl()->NullIdentifier();
2539 2540 2541
  Token::Value name_token = peek();
  int next_beg_pos = scanner()->peek_location().beg_pos;
  int next_end_pos = scanner()->peek_location().end_pos;
2542

2543 2544 2545
  ExpressionT name_expression =
      ParsePropertyName(&name, &kind, &is_generator, &is_async,
                        is_computed_name, CHECK_OK_CUSTOM(NullLiteralProperty));
2546

2547
  switch (kind) {
2548
    case PropertyKind::kSpreadProperty:
2549
      DCHECK(!is_generator && !is_async && !*is_computed_name);
2550
      DCHECK_EQ(Token::ELLIPSIS, name_token);
2551 2552

      *is_computed_name = true;
2553
      *is_rest_property = true;
2554 2555

      return factory()->NewObjectLiteralProperty(
2556
          factory()->NewTheHoleLiteral(), name_expression,
2557 2558
          ObjectLiteralProperty::SPREAD, true);

2559
    case PropertyKind::kValueProperty: {
2560
      DCHECK(!is_generator && !is_async);
2561 2562

      if (!*is_computed_name) {
2563
        checker->CheckDuplicateProto(name_token);
2564 2565
      }
      Consume(Token::COLON);
2566
      int beg_pos = peek_position();
2567 2568
      ExpressionT value =
          ParseAssignmentExpression(true, CHECK_OK_CUSTOM(NullLiteralProperty));
2569
      CheckDestructuringElement(value, beg_pos, scanner()->location().end_pos);
2570

2571 2572
      ObjectLiteralPropertyT result = factory()->NewObjectLiteralProperty(
          name_expression, value, *is_computed_name);
2573
      impl()->SetFunctionNameFromPropertyName(result, name);
2574
      return result;
2575 2576
    }

2577
    case PropertyKind::kShorthandProperty: {
2578 2579 2580 2581 2582 2583
      // PropertyDefinition
      //    IdentifierReference
      //    CoverInitializedName
      //
      // CoverInitializedName
      //    IdentifierReference Initializer?
2584
      DCHECK(!is_generator && !is_async);
2585 2586 2587 2588 2589

      if (!Token::IsIdentifier(name_token, language_mode(),
                               this->is_generator(),
                               parsing_module_ || is_async_function())) {
        ReportUnexpectedToken(Next());
2590
        *ok = false;
2591
        return impl()->NullLiteralProperty();
2592 2593
      }

2594
      DCHECK(!*is_computed_name);
2595

2596
      if (classifier()->duplicate_finder() != nullptr &&
2597 2598
          scanner()->IsDuplicateSymbol(classifier()->duplicate_finder(),
                                       ast_value_factory())) {
2599 2600
        classifier()->RecordDuplicateFormalParameterError(
            scanner()->location());
2601
      }
2602

2603
      if (impl()->IsEvalOrArguments(name) && is_strict(language_mode())) {
2604
        classifier()->RecordBindingPatternError(
2605 2606 2607
            scanner()->location(), MessageTemplate::kStrictEvalArguments);
      }

2608
      if (name_token == Token::LET) {
2609
        classifier()->RecordLetPatternError(
2610 2611
            scanner()->location(), MessageTemplate::kLetInLexicalBinding);
      }
2612 2613
      if (name_token == Token::AWAIT) {
        DCHECK(!is_async_function());
2614
        classifier()->RecordAsyncArrowFormalParametersError(
2615 2616
            Scanner::Location(next_beg_pos, next_end_pos),
            MessageTemplate::kAwaitBindingIdentifier);
2617
      }
2618
      ExpressionT lhs = impl()->ExpressionFromIdentifier(name, next_beg_pos);
2619
      CheckDestructuringElement(lhs, next_beg_pos, next_end_pos);
2620

2621
      ExpressionT value;
2622 2623
      if (peek() == Token::ASSIGN) {
        Consume(Token::ASSIGN);
2624
        ExpressionClassifier rhs_classifier(this);
2625
        ExpressionT rhs = ParseAssignmentExpression(
2626
            true, CHECK_OK_CUSTOM(NullLiteralProperty));
2627
        ValidateExpression(CHECK_OK_CUSTOM(NullLiteralProperty));
2628
        AccumulateFormalParameterContainmentErrors();
2629
        value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs,
yangguo's avatar
yangguo committed
2630
                                         kNoSourcePosition);
2631
        classifier()->RecordExpressionError(
2632 2633
            Scanner::Location(next_beg_pos, scanner()->location().end_pos),
            MessageTemplate::kInvalidCoverInitializedName);
2634

2635
        impl()->SetFunctionNameFromIdentifierRef(rhs, lhs);
2636 2637 2638 2639
      } else {
        value = lhs;
      }

2640
      ObjectLiteralPropertyT result = factory()->NewObjectLiteralProperty(
2641
          name_expression, value, ObjectLiteralProperty::COMPUTED, false);
2642 2643
      impl()->SetFunctionNameFromPropertyName(result, name);
      return result;
2644 2645
    }

2646 2647 2648 2649
    case PropertyKind::kMethodProperty: {
      // MethodDefinition
      //    PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
      //    '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2650

2651
      classifier()->RecordPatternError(
2652 2653
          Scanner::Location(next_beg_pos, scanner()->location().end_pos),
          MessageTemplate::kInvalidDestructuringTarget);
2654

2655
      FunctionKind kind = MethodKindFor(is_generator, is_async);
2656

2657
      ExpressionT value = impl()->ParseFunctionLiteral(
2658
          name, scanner()->location(), kSkipFunctionNameCheck, kind,
2659
          FLAG_harmony_function_tostring ? next_beg_pos : kNoSourcePosition,
2660
          FunctionLiteral::kAccessorOrMethod, language_mode(), nullptr,
2661
          CHECK_OK_CUSTOM(NullLiteralProperty));
2662

2663
      ObjectLiteralPropertyT result = factory()->NewObjectLiteralProperty(
2664
          name_expression, value, ObjectLiteralProperty::COMPUTED,
2665
          *is_computed_name);
2666 2667
      impl()->SetFunctionNameFromPropertyName(result, name);
      return result;
2668
    }
2669

2670 2671 2672 2673
    case PropertyKind::kAccessorGetterProperty:
    case PropertyKind::kAccessorSetterProperty: {
      DCHECK(!is_generator && !is_async);
      bool is_get = kind == PropertyKind::kAccessorGetterProperty;
2674

2675
      classifier()->RecordPatternError(
2676 2677 2678 2679
          Scanner::Location(next_beg_pos, scanner()->location().end_pos),
          MessageTemplate::kInvalidDestructuringTarget);

      if (!*is_computed_name) {
2680 2681 2682
        // Make sure the name expression is a string since we need a Name for
        // Runtime_DefineAccessorPropertyUnchecked and since we can determine
        // this statically we can skip the extra runtime check.
2683
        name_expression =
2684
            factory()->NewStringLiteral(name, name_expression->position());
2685
      }
2686

2687 2688 2689
      FunctionKind kind = is_get ? FunctionKind::kGetterFunction
                                 : FunctionKind::kSetterFunction;

2690 2691
      FunctionLiteralT value = impl()->ParseFunctionLiteral(
          name, scanner()->location(), kSkipFunctionNameCheck, kind,
2692
          FLAG_harmony_function_tostring ? next_beg_pos : kNoSourcePosition,
2693
          FunctionLiteral::kAccessorOrMethod, language_mode(), nullptr,
2694
          CHECK_OK_CUSTOM(NullLiteralProperty));
2695

2696 2697 2698 2699
      ObjectLiteralPropertyT result = factory()->NewObjectLiteralProperty(
          name_expression, value,
          is_get ? ObjectLiteralProperty::GETTER
                 : ObjectLiteralProperty::SETTER,
2700
          *is_computed_name);
2701 2702 2703 2704 2705
      const AstRawString* prefix =
          is_get ? ast_value_factory()->get_space_string()
                 : ast_value_factory()->set_space_string();
      impl()->SetFunctionNameFromPropertyName(result, name, prefix);
      return result;
2706
    }
2707

2708
    case PropertyKind::kClassField:
2709
    case PropertyKind::kNotSet:
2710 2711
      ReportUnexpectedToken(Next());
      *ok = false;
2712
      return impl()->NullLiteralProperty();
2713
  }
2714
  UNREACHABLE();
2715 2716
}

2717 2718
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral(
2719
    bool* ok) {
2720 2721 2722 2723
  // ObjectLiteral ::
  // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}'

  int pos = peek_position();
2724 2725
  typename Types::ObjectPropertyList properties =
      impl()->NewObjectPropertyList(4);
2726
  int number_of_boilerplate_properties = 0;
2727

2728
  bool has_computed_names = false;
2729
  bool has_rest_property = false;
2730 2731
  ObjectLiteralChecker checker(this);

2732
  Consume(Token::LBRACE);
2733 2734

  while (peek() != Token::RBRACE) {
2735
    FuncNameInferrer::State fni_state(fni_);
2736 2737

    bool is_computed_name = false;
2738 2739 2740
    bool is_rest_property = false;
    ObjectLiteralPropertyT property = ParseObjectPropertyDefinition(
        &checker, &is_computed_name, &is_rest_property, CHECK_OK);
2741 2742 2743 2744 2745

    if (is_computed_name) {
      has_computed_names = true;
    }

2746 2747 2748 2749
    if (is_rest_property) {
      has_rest_property = true;
    }

2750
    if (impl()->IsBoilerplateProperty(property) && !has_computed_names) {
2751 2752
      // Count CONSTANT or COMPUTED properties to maintain the enumeration
      // order.
2753 2754
      number_of_boilerplate_properties++;
    }
2755

2756 2757 2758 2759 2760 2761 2762
    properties->Add(property, zone());

    if (peek() != Token::RBRACE) {
      // Need {} because of the CHECK_OK macro.
      Expect(Token::COMMA, CHECK_OK);
    }

2763
    if (fni_ != nullptr) fni_->Infer();
2764 2765 2766
  }
  Expect(Token::RBRACE, CHECK_OK);

2767 2768 2769 2770 2771 2772 2773 2774 2775 2776
  // In pattern rewriter, we rewrite rest property to call out to a
  // runtime function passing all the other properties as arguments to
  // this runtime function. Here, we make sure that the number of
  // properties is less than number of arguments allowed for a runtime
  // call.
  if (has_rest_property && properties->length() > Code::kMaxArguments) {
    this->classifier()->RecordPatternError(Scanner::Location(pos, position()),
                                           MessageTemplate::kTooManyArguments);
  }

2777 2778
  return impl()->InitializeObjectLiteral(factory()->NewObjectLiteral(
      properties, number_of_boilerplate_properties, pos, has_rest_property));
2779 2780
}

2781
template <typename Impl>
2782
typename ParserBase<Impl>::ExpressionListT ParserBase<Impl>::ParseArguments(
2783 2784
    Scanner::Location* first_spread_arg_loc, bool maybe_arrow,
    bool* is_simple_parameter_list, bool* ok) {
2785 2786 2787 2788
  // Arguments ::
  //   '(' (AssignmentExpression)*[','] ')'

  Scanner::Location spread_arg = Scanner::Location::invalid();
2789
  ExpressionListT result = impl()->NewExpressionList(4);
2790 2791 2792 2793 2794
  Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList));
  bool done = (peek() == Token::RPAREN);
  while (!done) {
    int start_pos = peek_position();
    bool is_spread = Check(Token::ELLIPSIS);
nikolaos's avatar
nikolaos committed
2795
    int expr_pos = peek_position();
2796

2797 2798
    ExpressionT argument =
        ParseAssignmentExpression(true, CHECK_OK_CUSTOM(NullExpressionList));
2799 2800 2801 2802
    if (!impl()->IsIdentifier(argument) &&
        is_simple_parameter_list != nullptr) {
      *is_simple_parameter_list = false;
    }
2803
    if (!maybe_arrow) {
2804
      ValidateExpression(CHECK_OK_CUSTOM(NullExpressionList));
2805
    }
2806
    if (is_spread) {
2807 2808 2809
      if (is_simple_parameter_list != nullptr) {
        *is_simple_parameter_list = false;
      }
2810 2811 2812 2813
      if (!spread_arg.IsValid()) {
        spread_arg.beg_pos = start_pos;
        spread_arg.end_pos = peek_position();
      }
2814 2815 2816 2817
      if (argument->IsAssignment()) {
        classifier()->RecordAsyncArrowFormalParametersError(
            scanner()->location(), MessageTemplate::kRestDefaultInitializer);
      }
nikolaos's avatar
nikolaos committed
2818
      argument = factory()->NewSpread(argument, start_pos, expr_pos);
2819 2820 2821 2822 2823 2824
    }
    result->Add(argument, zone_);

    if (result->length() > Code::kMaxArguments) {
      ReportMessage(MessageTemplate::kTooManyArguments);
      *ok = false;
2825
      return impl()->NullExpressionList();
2826 2827 2828 2829
    }
    done = (peek() != Token::COMMA);
    if (!done) {
      Next();
2830 2831 2832 2833
      if (argument->IsSpread()) {
        classifier()->RecordAsyncArrowFormalParametersError(
            scanner()->location(), MessageTemplate::kParamAfterRest);
      }
2834
      if (peek() == Token::RPAREN) {
2835 2836 2837
        // allow trailing comma
        done = true;
      }
2838 2839 2840 2841
    }
  }
  Scanner::Location location = scanner_->location();
  if (Token::RPAREN != Next()) {
2842
    impl()->ReportMessageAt(location, MessageTemplate::kUnterminatedArgList);
2843
    *ok = false;
2844
    return impl()->NullExpressionList();
2845 2846 2847
  }
  *first_spread_arg_loc = spread_arg;

2848 2849
  if (!maybe_arrow || peek() != Token::ARROW) {
    if (maybe_arrow) {
2850
      ValidateExpression(CHECK_OK_CUSTOM(NullExpressionList));
2851
    }
2852 2853 2854 2855 2856 2857
  }

  return result;
}

// Precedence = 2
2858 2859
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
2860
ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
2861 2862 2863 2864 2865 2866 2867 2868
  // AssignmentExpression ::
  //   ConditionalExpression
  //   ArrowFunction
  //   YieldExpression
  //   LeftHandSideExpression AssignmentOperator AssignmentExpression
  int lhs_beg_pos = peek_position();

  if (peek() == Token::YIELD && is_generator()) {
2869
    return ParseYieldExpression(accept_IN, ok);
2870 2871
  }

2872
  FuncNameInferrer::State fni_state(fni_);
2873 2874
  ExpressionClassifier arrow_formals_classifier(
      this, classifier()->duplicate_finder());
2875

2876
  Scope::Snapshot scope_snapshot(scope());
2877 2878
  int rewritable_length = static_cast<int>(
      function_state_->destructuring_assignments_to_rewrite().size());
2879

2880
  bool is_async = peek() == Token::ASYNC &&
2881
                  !scanner()->HasLineTerminatorAfterNext() &&
2882
                  IsValidArrowFormalParametersStart(PeekAhead());
2883

2884
  bool parenthesized_formals = peek() == Token::LPAREN;
2885
  if (!is_async && !parenthesized_formals) {
2886
    ArrowFormalParametersUnexpectedToken();
2887
  }
2888

2889 2890 2891 2892 2893 2894 2895 2896
  // Parse a simple, faster sub-grammar (primary expression) if it's evident
  // that we have only a trivial expression to parse.
  ExpressionT expression;
  if (IsTrivialExpression()) {
    expression = ParsePrimaryExpression(&is_async, CHECK_OK);
  } else {
    expression = ParseConditionalExpression(accept_IN, CHECK_OK);
  }
2897

2898
  if (is_async && impl()->IsIdentifier(expression) && peek_any_identifier() &&
2899
      PeekAhead() == Token::ARROW) {
2900
    // async Identifier => AsyncConciseBody
2901
    IdentifierT name = ParseAndClassifyIdentifier(CHECK_OK);
2902 2903
    expression =
        impl()->ExpressionFromIdentifier(name, position(), InferName::kNo);
2904 2905 2906 2907
    if (fni_) {
      // Remove `async` keyword from inferred name stack.
      fni_->RemoveAsyncKeywordFromEnd();
    }
2908 2909
  }

2910
  if (peek() == Token::ARROW) {
2911
    Scanner::Location arrow_loc = scanner()->peek_location();
2912 2913
    ValidateArrowFormalParameters(expression, parenthesized_formals, is_async,
                                  CHECK_OK);
2914 2915 2916 2917 2918 2919
    // 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
    // in an arrow parameter list, this is correct.
    // TODO(adamk): Rename "FormalParameterInitializerError" to refer to
    // "YieldExpression", which is its only use.
2920
    ValidateFormalParameterInitializer(ok);
2921

2922
    Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos);
2923
    DeclarationScope* scope =
2924 2925
        NewFunctionScope(is_async ? FunctionKind::kAsyncArrowFunction
                                  : FunctionKind::kArrowFunction);
2926

2927 2928
    // Because the arrow's parameters were parsed in the outer scope,
    // we need to fix up the scope chain appropriately.
2929 2930
    scope_snapshot.Reparent(scope);

2931
    FormalParametersT parameters(scope);
2932
    if (!classifier()->is_simple_parameter_list()) {
2933 2934 2935 2936 2937
      scope->SetHasNonSimpleParameters();
      parameters.is_simple = false;
    }

    scope->set_start_position(lhs_beg_pos);
2938
    Scanner::Location duplicate_loc = Scanner::Location::invalid();
2939 2940
    impl()->DeclareArrowFunctionFormalParameters(&parameters, expression, loc,
                                                 &duplicate_loc, CHECK_OK);
2941
    if (duplicate_loc.IsValid()) {
2942
      classifier()->RecordDuplicateFormalParameterError(duplicate_loc);
2943
    }
2944 2945
    expression = ParseArrowFunctionLiteral(accept_IN, parameters,
                                           rewritable_length, CHECK_OK);
2946
    Accumulate(ExpressionClassifier::AsyncArrowFormalParametersProduction);
2947 2948 2949
    classifier()->RecordPatternError(arrow_loc,
                                     MessageTemplate::kUnexpectedToken,
                                     Token::String(Token::ARROW));
2950 2951 2952

    if (fni_ != nullptr) fni_->Infer();

2953 2954 2955
    return expression;
  }

2956 2957 2958 2959
  // "expression" was not itself an arrow function parameter list, but it might
  // form part of one.  Propagate speculative formal parameter error locations
  // (including those for binding patterns, since formal parameters can
  // themselves contain binding patterns).
2960 2961
  unsigned productions = ExpressionClassifier::AllProductions &
                         ~ExpressionClassifier::ArrowFormalParametersProduction;
2962 2963

  // Parenthesized identifiers and property references are allowed as part
2964
  // of a larger assignment pattern, even though parenthesized patterns
2965 2966
  // themselves are not allowed, e.g., "[(x)] = []". Only accumulate
  // assignment pattern errors if the parsed expression is more complex.
2967
  if (IsValidReferenceExpression(expression)) {
2968
    productions &= ~ExpressionClassifier::AssignmentPatternProduction;
2969 2970
  }

2971 2972
  const bool is_destructuring_assignment =
      IsValidPattern(expression) && peek() == Token::ASSIGN;
2973 2974 2975
  if (is_destructuring_assignment) {
    // This is definitely not an expression so don't accumulate
    // expression-related errors.
2976
    productions &= ~ExpressionClassifier::ExpressionProduction;
2977 2978
  }

2979 2980
  Accumulate(productions);
  if (!Token::IsAssignmentOp(peek())) return expression;
2981

2982
  if (is_destructuring_assignment) {
2983
    ValidateAssignmentPattern(CHECK_OK);
2984
  } else {
2985
    expression = CheckAndRewriteReferenceExpression(
2986 2987 2988 2989
        expression, lhs_beg_pos, scanner()->location().end_pos,
        MessageTemplate::kInvalidLhsInAssignment, CHECK_OK);
  }

2990
  impl()->MarkExpressionAsAssigned(expression);
2991 2992 2993

  Token::Value op = Next();  // Get assignment operator.
  if (op != Token::ASSIGN) {
2994 2995 2996
    classifier()->RecordPatternError(scanner()->location(),
                                     MessageTemplate::kUnexpectedToken,
                                     Token::String(op));
2997 2998 2999
  }
  int pos = position();

3000
  ExpressionClassifier rhs_classifier(this);
3001

3002
  ExpressionT right = ParseAssignmentExpression(accept_IN, CHECK_OK);
3003
  ValidateExpression(CHECK_OK);
3004
  AccumulateFormalParameterContainmentErrors();
3005

3006 3007 3008 3009
  // We try to estimate the set of properties set by constructors. We define a
  // new property whenever there is an assignment to a property of 'this'. We
  // should probably only add properties if we haven't seen them
  // before. Otherwise we'll probably overestimate the number of properties.
3010
  if (op == Token::ASSIGN && impl()->IsThisProperty(expression)) {
3011 3012 3013
    function_state_->AddProperty();
  }

3014 3015
  impl()->CheckAssigningFunctionLiteralToProperty(expression, right);

3016
  if (fni_ != nullptr) {
3017 3018 3019
    // Check if the right hand side is a call to avoid inferring a
    // name if we're dealing with "a = function(){...}();"-like
    // expression.
3020
    if (op == Token::ASSIGN && !right->IsCall() && !right->IsCallNew()) {
3021 3022 3023 3024 3025 3026
      fni_->Infer();
    } else {
      fni_->RemoveLastFunction();
    }
  }

3027
  if (op == Token::ASSIGN) {
3028
    impl()->SetFunctionNameFromIdentifierRef(right, expression);
3029 3030
  }

3031
  DCHECK_NE(op, Token::INIT);
3032 3033 3034
  ExpressionT result = factory()->NewAssignment(op, expression, right, pos);

  if (is_destructuring_assignment) {
3035
    DCHECK_NE(op, Token::ASSIGN_EXP);
3036 3037 3038
    auto rewritable = factory()->NewRewritableExpression(result, scope());
    impl()->QueueDestructuringAssignmentForRewriting(rewritable);
    result = rewritable;
3039 3040 3041 3042 3043
  }

  return result;
}

3044 3045
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseYieldExpression(
3046
    bool accept_IN, bool* ok) {
3047 3048 3049
  // YieldExpression ::
  //   'yield' ([no line terminator] '*'? AssignmentExpression)?
  int pos = peek_position();
3050 3051 3052
  classifier()->RecordPatternError(
      scanner()->peek_location(), MessageTemplate::kInvalidDestructuringTarget);
  classifier()->RecordFormalParameterInitializerError(
3053
      scanner()->peek_location(), MessageTemplate::kYieldInParameter);
3054
  Expect(Token::YIELD, CHECK_OK);
3055
  // The following initialization is necessary.
3056
  ExpressionT expression = impl()->NullExpression();
3057
  bool delegating = false;  // yield*
3058
  if (!scanner()->HasLineTerminatorBeforeNext()) {
3059
    if (Check(Token::MUL)) delegating = true;
3060 3061 3062 3063 3064 3065 3066 3067
    switch (peek()) {
      case Token::EOS:
      case Token::SEMICOLON:
      case Token::RBRACE:
      case Token::RBRACK:
      case Token::RPAREN:
      case Token::COLON:
      case Token::COMMA:
3068
      case Token::IN:
3069 3070 3071
        // The above set of tokens is the complete set of tokens that can appear
        // after an AssignmentExpression, and none of them can start an
        // AssignmentExpression.  This allows us to avoid looking for an RHS for
3072 3073
        // a regular yield, given only one look-ahead token.
        if (!delegating) break;
3074
        // Delegating yields require an RHS; fall through.
3075
        V8_FALLTHROUGH;
3076
      default:
3077
        expression = ParseAssignmentExpression(accept_IN, CHECK_OK);
3078
        ValidateExpression(CHECK_OK);
3079 3080 3081
        break;
    }
  }
3082 3083

  if (delegating) {
3084 3085
    ExpressionT yieldstar = factory()->NewYieldStar(expression, pos);
    impl()->RecordSuspendSourceRange(yieldstar, PositionAfterSemicolon());
3086 3087 3088 3089 3090 3091
    function_state_->AddSuspend();
    if (IsAsyncGeneratorFunction(function_state_->kind())) {
      // iterator_close and delegated_iterator_output suspend ids.
      function_state_->AddSuspend();
      function_state_->AddSuspend();
    }
3092
    return yieldstar;
3093
  }
3094

3095 3096
  // Hackily disambiguate o from o.next and o [Symbol.iterator]().
  // TODO(verwaest): Come up with a better solution.
3097 3098
  ExpressionT yield =
      factory()->NewYield(expression, pos, Suspend::kOnExceptionThrow);
3099
  impl()->RecordSuspendSourceRange(yield, PositionAfterSemicolon());
3100
  function_state_->AddSuspend();
3101 3102 3103 3104
  return yield;
}

// Precedence = 3
3105 3106 3107 3108
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseConditionalExpression(bool accept_IN,
                                             bool* ok) {
3109 3110 3111 3112
  // ConditionalExpression ::
  //   LogicalOrExpression
  //   LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression

3113
  SourceRange then_range, else_range;
3114 3115
  int pos = peek_position();
  // We start using the binary expression parser for prec >= 4 only!
3116
  ExpressionT expression = ParseBinaryExpression(4, accept_IN, CHECK_OK);
3117
  if (peek() != Token::CONDITIONAL) return expression;
3118
  ValidateExpression(CHECK_OK);
3119 3120
  BindingPatternUnexpectedToken();
  ArrowFormalParametersUnexpectedToken();
3121 3122 3123

  ExpressionT left;
  {
3124
    SourceRangeScope range_scope(scanner(), &then_range);
3125
    Consume(Token::CONDITIONAL);
3126 3127 3128 3129 3130
    ExpressionClassifier classifier(this);
    // In parsing the first assignment expression in conditional
    // expressions we always accept the 'in' keyword; see ECMA-262,
    // section 11.12, page 58.
    left = ParseAssignmentExpression(true, CHECK_OK);
3131
    AccumulateNonBindingPatternErrors();
3132
  }
3133
  ValidateExpression(CHECK_OK);
3134 3135
  ExpressionT right;
  {
3136
    SourceRangeScope range_scope(scanner(), &else_range);
3137
    Expect(Token::COLON, CHECK_OK);
3138 3139
    ExpressionClassifier classifier(this);
    right = ParseAssignmentExpression(accept_IN, CHECK_OK);
3140
    AccumulateNonBindingPatternErrors();
3141
  }
3142
  ValidateExpression(CHECK_OK);
3143 3144 3145
  ExpressionT expr = factory()->NewConditional(expression, left, right, pos);
  impl()->RecordConditionalSourceRange(expr, then_range, else_range);
  return expr;
3146 3147 3148 3149
}


// Precedence >= 4
3150 3151
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBinaryExpression(
3152
    int prec, bool accept_IN, bool* ok) {
3153
  DCHECK_GE(prec, 4);
3154
  SourceRange right_range;
3155
  ExpressionT x = ParseUnaryExpression(CHECK_OK);
3156 3157 3158
  for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
    // prec1 >= 4
    while (Precedence(peek(), accept_IN) == prec1) {
3159
      ValidateExpression(CHECK_OK);
3160 3161
      BindingPatternUnexpectedToken();
      ArrowFormalParametersUnexpectedToken();
3162 3163

      SourceRangeScope right_range_scope(scanner(), &right_range);
3164 3165
      Token::Value op = Next();
      int pos = position();
3166 3167 3168

      const bool is_right_associative = op == Token::EXP;
      const int next_prec = is_right_associative ? prec1 : prec1 + 1;
3169
      ExpressionT y = ParseBinaryExpression(next_prec, accept_IN, CHECK_OK);
3170
      right_range_scope.Finalize();
3171
      ValidateExpression(CHECK_OK);
3172

3173
      if (impl()->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos)) {
3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187
        continue;
      }

      // For now we distinguish between comparisons and other binary
      // operations.  (We could combine the two and get rid of this
      // code and AST node eventually.)
      if (Token::IsCompareOp(op)) {
        // We have a comparison.
        Token::Value cmp = op;
        switch (op) {
          case Token::NE: cmp = Token::EQ; break;
          case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
          default: break;
        }
3188 3189 3190 3191
        x = factory()->NewCompareOperation(cmp, x, y, pos);
        if (cmp != op) {
          // The comparison was negated - add a NOT.
          x = factory()->NewUnaryOperation(Token::NOT, x, pos);
3192
        }
3193
      } else if (impl()->CollapseNaryExpression(&x, y, op, pos, right_range)) {
3194
        continue;
3195 3196 3197
      } else {
        // We have a "normal" binary operation.
        x = factory()->NewBinaryOperation(op, x, y, pos);
3198 3199 3200
        if (op == Token::OR || op == Token::AND) {
          impl()->RecordBinaryOperationSourceRange(x, right_range);
        }
3201 3202 3203 3204 3205 3206
      }
    }
  }
  return x;
}

3207 3208
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseUnaryExpression(
3209
    bool* ok) {
3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220
  // UnaryExpression ::
  //   PostfixExpression
  //   'delete' UnaryExpression
  //   'void' UnaryExpression
  //   'typeof' UnaryExpression
  //   '++' UnaryExpression
  //   '--' UnaryExpression
  //   '+' UnaryExpression
  //   '-' UnaryExpression
  //   '~' UnaryExpression
  //   '!' UnaryExpression
3221
  //   [+Await] AwaitExpression[?Yield]
3222 3223 3224

  Token::Value op = peek();
  if (Token::IsUnaryOp(op)) {
3225 3226
    BindingPatternUnexpectedToken();
    ArrowFormalParametersUnexpectedToken();
3227 3228 3229

    op = Next();
    int pos = position();
3230 3231 3232 3233 3234 3235

    // Assume "! function ..." indicates the function is likely to be called.
    if (op == Token::NOT && peek() == Token::FUNCTION) {
      function_state_->set_next_function_is_likely_called();
    }

3236
    ExpressionT expression = ParseUnaryExpression(CHECK_OK);
3237
    ValidateExpression(CHECK_OK);
3238

3239 3240
    if (op == Token::DELETE) {
      if (impl()->IsIdentifier(expression) && is_strict(language_mode())) {
3241 3242 3243
        // "delete identifier" is a syntax error in strict mode.
        ReportMessage(MessageTemplate::kStrictDelete);
        *ok = false;
3244
        return impl()->NullExpression();
3245
      }
3246 3247 3248 3249 3250 3251

      if (impl()->IsPropertyWithPrivateFieldKey(expression)) {
        ReportMessage(MessageTemplate::kDeletePrivateField);
        *ok = false;
        return impl()->NullExpression();
      }
3252 3253
    }

3254 3255 3256
    if (peek() == Token::EXP) {
      ReportUnexpectedToken(Next());
      *ok = false;
3257
      return impl()->NullExpression();
3258 3259
    }

3260
    // Allow the parser's implementation to rewrite the expression.
3261
    return impl()->BuildUnaryExpression(expression, op, pos);
3262
  } else if (Token::IsCountOp(op)) {
3263 3264
    BindingPatternUnexpectedToken();
    ArrowFormalParametersUnexpectedToken();
3265 3266
    op = Next();
    int beg_pos = peek_position();
3267
    ExpressionT expression = ParseUnaryExpression(CHECK_OK);
3268
    expression = CheckAndRewriteReferenceExpression(
3269 3270
        expression, beg_pos, scanner()->location().end_pos,
        MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK);
3271
    impl()->MarkExpressionAsAssigned(expression);
3272
    ValidateExpression(CHECK_OK);
3273 3274 3275 3276 3277 3278

    return factory()->NewCountOperation(op,
                                        true /* prefix */,
                                        expression,
                                        position());

3279
  } else if (is_async_function() && peek() == Token::AWAIT) {
3280
    classifier()->RecordFormalParameterInitializerError(
3281 3282
        scanner()->peek_location(),
        MessageTemplate::kAwaitExpressionFormalParameter);
3283
    int await_pos = peek_position();
3284 3285
    Consume(Token::AWAIT);

3286
    ExpressionT value = ParseUnaryExpression(CHECK_OK);
3287

3288 3289 3290 3291
    classifier()->RecordBindingPatternError(
        Scanner::Location(await_pos, scanner()->location().end_pos),
        MessageTemplate::kInvalidDestructuringTarget);

3292
    ExpressionT expr = factory()->NewAwait(value, await_pos);
3293
    function_state_->AddSuspend();
3294 3295
    impl()->RecordSuspendSourceRange(expr, PositionAfterSemicolon());
    return expr;
3296
  } else {
3297
    return ParsePostfixExpression(ok);
3298 3299 3300
  }
}

3301 3302
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePostfixExpression(
3303
    bool* ok) {
3304 3305 3306 3307
  // PostfixExpression ::
  //   LeftHandSideExpression ('++' | '--')?

  int lhs_beg_pos = peek_position();
3308
  ExpressionT expression = ParseLeftHandSideExpression(CHECK_OK);
3309
  if (!scanner()->HasLineTerminatorBeforeNext() && Token::IsCountOp(peek())) {
3310 3311
    BindingPatternUnexpectedToken();
    ArrowFormalParametersUnexpectedToken();
3312

3313
    expression = CheckAndRewriteReferenceExpression(
3314 3315
        expression, lhs_beg_pos, scanner()->location().end_pos,
        MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK);
3316
    impl()->MarkExpressionAsAssigned(expression);
3317
    ValidateExpression(CHECK_OK);
3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328

    Token::Value next = Next();
    expression =
        factory()->NewCountOperation(next,
                                     false /* postfix */,
                                     expression,
                                     position());
  }
  return expression;
}

3329 3330
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
3331
ParserBase<Impl>::ParseLeftHandSideExpression(bool* ok) {
3332 3333 3334
  // LeftHandSideExpression ::
  //   (NewExpression | MemberExpression) ...

3335
  bool is_async = false;
3336
  ExpressionT result =
3337
      ParseMemberWithNewPrefixesExpression(&is_async, CHECK_OK);
3338 3339 3340 3341

  while (true) {
    switch (peek()) {
      case Token::LBRACK: {
3342
        ValidateExpression(CHECK_OK);
3343 3344
        BindingPatternUnexpectedToken();
        ArrowFormalParametersUnexpectedToken();
3345 3346
        Consume(Token::LBRACK);
        int pos = position();
3347
        ExpressionT index = ParseExpressionCoverGrammar(true, CHECK_OK);
3348
        ValidateExpression(CHECK_OK);
3349 3350 3351 3352 3353 3354
        result = factory()->NewProperty(result, index, pos);
        Expect(Token::RBRACK, CHECK_OK);
        break;
      }

      case Token::LPAREN: {
3355
        int pos;
3356
        ValidateExpression(CHECK_OK);
3357
        BindingPatternUnexpectedToken();
3358
        if (scanner()->current_token() == Token::IDENTIFIER ||
3359 3360
            scanner()->current_token() == Token::SUPER ||
            scanner()->current_token() == Token::ASYNC) {
3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373
          // For call of an identifier we want to report position of
          // the identifier as position of the call in the stack trace.
          pos = position();
        } else {
          // For other kinds of calls we record position of the parenthesis as
          // position of the call. Note that this is extremely important for
          // expressions of the form function(){...}() for which call position
          // should not point to the closing brace otherwise it will intersect
          // with positions recorded for function literal and confuse debugger.
          pos = peek_position();
          // Also the trailing parenthesis are a hint that the function will
          // be called immediately. If we happen to have parsed a preceding
          // function literal eagerly, we can also compile it eagerly.
3374
          if (result->IsFunctionLiteral()) {
3375
            result->AsFunctionLiteral()->SetShouldEagerCompile();
3376
            result->AsFunctionLiteral()->mark_as_iife();
3377 3378 3379
          }
        }
        Scanner::Location spread_pos;
3380
        ExpressionListT args;
3381
        if (V8_UNLIKELY(is_async && impl()->IsIdentifier(result))) {
3382
          ExpressionClassifier async_classifier(this);
3383 3384 3385
          bool is_simple_parameter_list = true;
          args = ParseArguments(&spread_pos, true, &is_simple_parameter_list,
                                CHECK_OK);
3386
          if (peek() == Token::ARROW) {
3387 3388 3389
            if (fni_) {
              fni_->RemoveAsyncKeywordFromEnd();
            }
3390 3391 3392
            ValidateBindingPattern(CHECK_OK);
            ValidateFormalParameterInitializer(CHECK_OK);
            if (!classifier()->is_valid_async_arrow_formal_parameters()) {
3393
              ReportClassifierError(
3394
                  classifier()->async_arrow_formal_parameters_error());
3395
              *ok = false;
3396
              return impl()->NullExpression();
3397 3398 3399
            }
            if (args->length()) {
              // async ( Arguments ) => ...
3400 3401 3402
              if (!is_simple_parameter_list) {
                async_classifier.previous()->RecordNonSimpleParameter();
              }
3403
              return impl()->ExpressionListToExpression(args);
3404 3405 3406 3407
            }
            // async () => ...
            return factory()->NewEmptyParentheses(pos);
          } else {
3408
            AccumulateFormalParameterContainmentErrors();
3409
          }
3410
        } else {
3411
          args = ParseArguments(&spread_pos, CHECK_OK);
3412 3413
        }

3414
        ArrowFormalParametersUnexpectedToken();
3415 3416 3417 3418 3419 3420 3421 3422

        // Keep track of eval() calls since they disable all local variable
        // optimizations.
        // The calls that need special treatment are the
        // direct eval calls. These calls are all of the form eval(...), with
        // no explicit receiver.
        // These calls are marked as potentially direct eval calls. Whether
        // they are actually direct calls to eval is determined at run time.
3423 3424
        Call::PossiblyEval is_possibly_eval =
            CheckPossibleEvalCall(result, scope());
3425 3426

        if (spread_pos.IsValid()) {
3427
          result = impl()->SpreadCall(result, args, pos, is_possibly_eval);
3428
        } else {
3429
          result = factory()->NewCall(result, args, pos, is_possibly_eval);
3430 3431
        }

3432
        if (fni_ != nullptr) fni_->RemoveLastFunction();
3433 3434 3435 3436
        break;
      }

      case Token::PERIOD: {
3437
        ValidateExpression(CHECK_OK);
3438 3439
        BindingPatternUnexpectedToken();
        ArrowFormalParametersUnexpectedToken();
3440 3441
        Consume(Token::PERIOD);
        int pos = position();
3442 3443
        ExpressionT key = ParseIdentifierNameOrPrivateName(CHECK_OK);
        result = factory()->NewProperty(result, key, pos);
3444 3445 3446 3447 3448
        break;
      }

      case Token::TEMPLATE_SPAN:
      case Token::TEMPLATE_TAIL: {
3449
        ValidateExpression(CHECK_OK);
3450 3451
        BindingPatternUnexpectedToken();
        ArrowFormalParametersUnexpectedToken();
3452
        result = ParseTemplateLiteral(result, position(), true, CHECK_OK);
3453 3454 3455 3456 3457 3458 3459 3460 3461
        break;
      }

      default:
        return result;
    }
  }
}

3462 3463
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
3464 3465
ParserBase<Impl>::ParseMemberWithNewPrefixesExpression(bool* is_async,
                                                       bool* ok) {
3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486
  // NewExpression ::
  //   ('new')+ MemberExpression
  //
  // NewTarget ::
  //   'new' '.' 'target'

  // The grammar for new expressions is pretty warped. We can have several 'new'
  // keywords following each other, and then a MemberExpression. When we see '('
  // after the MemberExpression, it's associated with the rightmost unassociated
  // 'new' to create a NewExpression with arguments. However, a NewExpression
  // can also occur without arguments.

  // Examples of new expression:
  // new foo.bar().baz means (new (foo.bar)()).baz
  // new foo()() means (new foo())()
  // new new foo()() means (new (new foo())())
  // new new foo means new (new foo)
  // new new foo() means new (new foo())
  // new new foo().bar().baz means (new (new foo()).bar()).baz

  if (peek() == Token::NEW) {
3487 3488
    BindingPatternUnexpectedToken();
    ArrowFormalParametersUnexpectedToken();
3489 3490
    Consume(Token::NEW);
    int new_pos = position();
3491
    ExpressionT result;
3492 3493
    if (peek() == Token::SUPER) {
      const bool is_new = true;
3494
      result = ParseSuperExpression(is_new, CHECK_OK);
3495 3496
    } else if (allow_harmony_dynamic_import() && peek() == Token::IMPORT &&
               (!allow_harmony_import_meta() || PeekAhead() == Token::LPAREN)) {
3497 3498 3499
      impl()->ReportMessageAt(scanner()->peek_location(),
                              MessageTemplate::kImportCallNotNewExpression);
      *ok = false;
3500
      return impl()->NullExpression();
3501
    } else if (peek() == Token::PERIOD) {
3502 3503 3504
      *is_async = false;
      result = ParseNewTargetExpression(CHECK_OK);
      return ParseMemberExpressionContinuation(result, is_async, CHECK_OK);
3505
    } else {
3506
      result = ParseMemberWithNewPrefixesExpression(is_async, CHECK_OK);
3507
    }
3508
    ValidateExpression(CHECK_OK);
3509 3510 3511
    if (peek() == Token::LPAREN) {
      // NewExpression with arguments.
      Scanner::Location spread_pos;
3512
      ExpressionListT args = ParseArguments(&spread_pos, CHECK_OK);
3513 3514

      if (spread_pos.IsValid()) {
3515
        result = impl()->SpreadCallNew(result, args, new_pos);
3516 3517 3518 3519
      } else {
        result = factory()->NewCallNew(result, args, new_pos);
      }
      // The expression can still continue with . or [ after the arguments.
3520
      result = ParseMemberExpressionContinuation(result, is_async, CHECK_OK);
3521 3522 3523
      return result;
    }
    // NewExpression without arguments.
3524
    return factory()->NewCallNew(result, impl()->NewExpressionList(0), new_pos);
3525 3526
  }
  // No 'new' or 'super' keyword.
3527
  return ParseMemberExpression(is_async, ok);
3528 3529
}

3530 3531
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseMemberExpression(
3532
    bool* is_async, bool* ok) {
3533 3534 3535
  // MemberExpression ::
  //   (PrimaryExpression | FunctionLiteral | ClassLiteral)
  //     ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
3536 3537 3538 3539 3540
  //
  // CallExpression ::
  //   (SuperCall | ImportCall)
  //     ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
  //
3541 3542 3543 3544 3545
  // The '[' Expression ']' and '.' Identifier parts are parsed by
  // ParseMemberExpressionContinuation, and the Arguments part is parsed by the
  // caller.

  // Parse the initial primary or function expression.
3546
  ExpressionT result;
3547
  if (peek() == Token::FUNCTION) {
3548 3549
    BindingPatternUnexpectedToken();
    ArrowFormalParametersUnexpectedToken();
3550 3551 3552

    Consume(Token::FUNCTION);
    int function_token_position = position();
3553

3554 3555 3556
    FunctionKind function_kind = Check(Token::MUL)
                                     ? FunctionKind::kGeneratorFunction
                                     : FunctionKind::kNormalFunction;
3557
    IdentifierT name = impl()->NullIdentifier();
3558 3559 3560
    bool is_strict_reserved_name = false;
    Scanner::Location function_name_location = Scanner::Location::invalid();
    FunctionLiteral::FunctionType function_type =
3561
        FunctionLiteral::kAnonymousExpression;
3562 3563 3564
    if (impl()->ParsingDynamicFunctionDeclaration()) {
      // We don't want dynamic functions to actually declare their name
      // "anonymous". We just want that name in the toString().
3565 3566
      if (stack_overflow()) {
        *ok = false;
3567
        return impl()->NullExpression();
3568
      }
3569
      Consume(Token::IDENTIFIER);
3570
      DCHECK(scanner()->CurrentMatchesContextual(Token::ANONYMOUS));
3571
    } else if (peek_any_identifier()) {
3572
      bool is_await = false;
3573
      name = ParseIdentifierOrStrictReservedWord(
3574
          function_kind, &is_strict_reserved_name, &is_await, CHECK_OK);
3575
      function_name_location = scanner()->location();
3576
      function_type = FunctionLiteral::kNamedExpression;
3577
    }
3578
    result = impl()->ParseFunctionLiteral(
3579 3580 3581
        name, function_name_location,
        is_strict_reserved_name ? kFunctionNameIsStrictReserved
                                : kFunctionNameValidityUnknown,
3582
        function_kind, function_token_position, function_type, language_mode(),
3583
        nullptr, CHECK_OK);
3584 3585
  } else if (peek() == Token::SUPER) {
    const bool is_new = false;
3586
    result = ParseSuperExpression(is_new, CHECK_OK);
3587
  } else if (allow_harmony_dynamic_import() && peek() == Token::IMPORT) {
3588
    result = ParseImportExpressions(CHECK_OK);
3589
  } else {
3590
    result = ParsePrimaryExpression(is_async, CHECK_OK);
3591 3592
  }

3593
  result = ParseMemberExpressionContinuation(result, is_async, CHECK_OK);
3594 3595 3596
  return result;
}

3597
template <typename Impl>
3598 3599
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseImportExpressions(
    bool* ok) {
3600
  DCHECK(allow_harmony_dynamic_import());
3601 3602 3603 3604 3605

  classifier()->RecordPatternError(scanner()->peek_location(),
                                   MessageTemplate::kUnexpectedToken,
                                   Token::String(Token::IMPORT));

3606 3607
  Consume(Token::IMPORT);
  int pos = position();
3608 3609 3610 3611 3612 3613 3614 3615 3616
  if (allow_harmony_import_meta() && peek() == Token::PERIOD) {
    ExpectMetaProperty(Token::META, "import.meta", pos, CHECK_OK);
    if (!parsing_module_) {
      impl()->ReportMessageAt(scanner()->location(),
                              MessageTemplate::kImportMetaOutsideModule);
      *ok = false;
      return impl()->NullExpression();
    }

3617
    return impl()->ImportMetaExpression(pos);
3618
  }
3619
  Expect(Token::LPAREN, CHECK_OK);
3620 3621 3622 3623 3624 3625
  if (peek() == Token::RPAREN) {
    impl()->ReportMessageAt(scanner()->location(),
                            MessageTemplate::kImportMissingSpecifier);
    *ok = false;
    return impl()->NullExpression();
  }
3626 3627
  ExpressionT arg = ParseAssignmentExpression(true, CHECK_OK);
  Expect(Token::RPAREN, CHECK_OK);
3628
  return factory()->NewImportCallExpression(arg, pos);
3629 3630
}

3631 3632 3633
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseSuperExpression(
    bool is_new, bool* ok) {
3634 3635 3636
  Expect(Token::SUPER, CHECK_OK);
  int pos = position();

3637
  DeclarationScope* scope = GetReceiverScope();
3638 3639 3640 3641 3642
  FunctionKind kind = scope->function_kind();
  if (IsConciseMethod(kind) || IsAccessorFunction(kind) ||
      IsClassConstructor(kind)) {
    if (peek() == Token::PERIOD || peek() == Token::LBRACK) {
      scope->RecordSuperPropertyUsage();
3643
      return impl()->NewSuperPropertyReference(pos);
3644 3645 3646
    }
    // new super() is never allowed.
    // super() is only allowed in derived constructor
3647
    if (!is_new && peek() == Token::LPAREN && IsDerivedConstructor(kind)) {
3648 3649
      // TODO(rossberg): This might not be the correct FunctionState for the
      // method here.
3650
      return impl()->NewSuperCallReference(pos);
3651 3652 3653
    }
  }

3654 3655
  impl()->ReportMessageAt(scanner()->location(),
                          MessageTemplate::kUnexpectedSuper);
3656
  *ok = false;
3657
  return impl()->NullExpression();
3658 3659
}

3660
template <typename Impl>
3661
void ParserBase<Impl>::ExpectMetaProperty(Token::Value property_name,
3662 3663
                                          const char* full_name, int pos,
                                          bool* ok) {
3664
  Consume(Token::PERIOD);
3665
  ExpectContextualKeyword(property_name, CHECK_OK_CUSTOM(Void));
3666
  if (scanner()->literal_contains_escapes()) {
3667
    impl()->ReportMessageAt(
3668 3669 3670 3671 3672
        Scanner::Location(pos, scanner()->location().end_pos),
        MessageTemplate::kInvalidEscapedMetaProperty, full_name);
    *ok = false;
  }
}
3673

3674 3675 3676
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseNewTargetExpression(bool* ok) {
3677
  int pos = position();
3678
  ExpectMetaProperty(Token::TARGET, "new.target", pos, CHECK_OK);
3679

3680 3681 3682 3683
  classifier()->RecordAssignmentPatternError(
      Scanner::Location(pos, scanner()->location().end_pos),
      MessageTemplate::kInvalidDestructuringTarget);

3684
  if (!GetReceiverScope()->is_function_scope()) {
3685 3686
    impl()->ReportMessageAt(scanner()->location(),
                            MessageTemplate::kUnexpectedNewTarget);
3687
    *ok = false;
3688
    return impl()->NullExpression();
3689 3690
  }

3691
  return impl()->NewTargetExpression(pos);
3692 3693
}

3694 3695
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
3696 3697
ParserBase<Impl>::ParseMemberExpressionContinuation(ExpressionT expression,
                                                    bool* is_async, bool* ok) {
3698 3699 3700 3701 3702
  // Parses this part of MemberExpression:
  // ('[' Expression ']' | '.' Identifier | TemplateLiteral)*
  while (true) {
    switch (peek()) {
      case Token::LBRACK: {
3703
        *is_async = false;
3704
        ValidateExpression(CHECK_OK);
3705 3706
        BindingPatternUnexpectedToken();
        ArrowFormalParametersUnexpectedToken();
3707 3708 3709

        Consume(Token::LBRACK);
        int pos = position();
3710
        ExpressionT index = ParseExpressionCoverGrammar(true, CHECK_OK);
3711
        ValidateExpression(CHECK_OK);
3712
        expression = factory()->NewProperty(expression, index, pos);
3713
        impl()->PushPropertyName(index);
3714 3715 3716 3717
        Expect(Token::RBRACK, CHECK_OK);
        break;
      }
      case Token::PERIOD: {
3718
        *is_async = false;
3719
        ValidateExpression(CHECK_OK);
3720 3721
        BindingPatternUnexpectedToken();
        ArrowFormalParametersUnexpectedToken();
3722 3723

        Consume(Token::PERIOD);
3724
        int pos = peek_position();
3725
        ExpressionT key = ParseIdentifierNameOrPrivateName(CHECK_OK);
3726
        expression = factory()->NewProperty(expression, key, pos);
3727 3728 3729 3730
        break;
      }
      case Token::TEMPLATE_SPAN:
      case Token::TEMPLATE_TAIL: {
3731
        *is_async = false;
3732
        ValidateExpression(CHECK_OK);
3733 3734
        BindingPatternUnexpectedToken();
        ArrowFormalParametersUnexpectedToken();
3735 3736 3737 3738 3739
        int pos;
        if (scanner()->current_token() == Token::IDENTIFIER) {
          pos = position();
        } else {
          pos = peek_position();
3740
          if (expression->IsFunctionLiteral()) {
3741 3742
            // If the tag function looks like an IIFE, set_parenthesized() to
            // force eager compilation.
3743
            expression->AsFunctionLiteral()->SetShouldEagerCompile();
3744 3745
          }
        }
3746
        expression = ParseTemplateLiteral(expression, pos, true, CHECK_OK);
3747 3748
        break;
      }
3749 3750 3751
      case Token::ILLEGAL: {
        ReportUnexpectedTokenAt(scanner()->peek_location(), Token::ILLEGAL);
        *ok = false;
3752
        return impl()->NullExpression();
3753
      }
3754 3755 3756 3757 3758
      default:
        return expression;
    }
  }
  DCHECK(false);
3759
  return impl()->NullExpression();
3760 3761
}

3762 3763 3764
template <typename Impl>
void ParserBase<Impl>::ParseFormalParameter(FormalParametersT* parameters,
                                            bool* ok) {
3765 3766 3767 3768
  // FormalParameter[Yield,GeneratorParameter] :
  //   BindingElement[?Yield, ?GeneratorParameter]
  bool is_rest = parameters->has_rest;

3769
  FuncNameInferrer::State fni_state(fni_);
3770 3771
  ExpressionT pattern = ParsePrimaryExpression(CHECK_OK_CUSTOM(Void));
  ValidateBindingPattern(CHECK_OK_CUSTOM(Void));
3772

3773
  if (!impl()->IsIdentifier(pattern)) {
3774
    parameters->is_simple = false;
3775 3776
    ValidateFormalParameterInitializer(CHECK_OK_CUSTOM(Void));
    classifier()->RecordNonSimpleParameter();
3777 3778
  }

3779
  ExpressionT initializer = impl()->NullExpression();
3780 3781 3782 3783 3784 3785
  if (Check(Token::ASSIGN)) {
    if (is_rest) {
      ReportMessage(MessageTemplate::kRestDefaultInitializer);
      *ok = false;
      return;
    }
3786
    ExpressionClassifier init_classifier(this);
3787
    initializer = ParseAssignmentExpression(true, CHECK_OK_CUSTOM(Void));
3788
    ValidateExpression(CHECK_OK_CUSTOM(Void));
3789
    ValidateFormalParameterInitializer(CHECK_OK_CUSTOM(Void));
3790
    parameters->is_simple = false;
3791
    DiscardExpressionClassifier();
3792
    classifier()->RecordNonSimpleParameter();
3793

3794
    impl()->SetFunctionNameFromIdentifierRef(initializer, pattern);
3795 3796
  }

3797
  impl()->AddFormalParameter(parameters, pattern, initializer,
3798 3799 3800
                             scanner()->location().end_pos, is_rest);
}

3801
template <typename Impl>
3802 3803
void ParserBase<Impl>::ParseFormalParameterList(FormalParametersT* parameters,
                                                bool* ok) {
3804
  // FormalParameters[Yield] :
3805 3806
  //   [empty]
  //   FunctionRestParameter[?Yield]
3807 3808 3809
  //   FormalParameterList[?Yield]
  //   FormalParameterList[?Yield] ,
  //   FormalParameterList[?Yield] , FunctionRestParameter[?Yield]
3810
  //
3811 3812 3813
  // FormalParameterList[Yield] :
  //   FormalParameter[?Yield]
  //   FormalParameterList[?Yield] , FormalParameter[?Yield]
3814

3815
  DCHECK_EQ(0, parameters->arity);
3816 3817

  if (peek() != Token::RPAREN) {
3818
    while (true) {
3819
      if (parameters->arity > Code::kMaxArguments) {
3820 3821 3822 3823
        ReportMessage(MessageTemplate::kTooManyParameters);
        *ok = false;
        return;
      }
3824
      parameters->has_rest = Check(Token::ELLIPSIS);
3825
      ParseFormalParameter(parameters, CHECK_OK_CUSTOM(Void));
3826

3827 3828
      if (parameters->has_rest) {
        parameters->is_simple = false;
3829
        classifier()->RecordNonSimpleParameter();
3830
        if (peek() == Token::COMMA) {
3831 3832
          impl()->ReportMessageAt(scanner()->peek_location(),
                                  MessageTemplate::kParamAfterRest);
3833 3834 3835 3836 3837 3838
          *ok = false;
          return;
        }
        break;
      }
      if (!Check(Token::COMMA)) break;
3839
      if (peek() == Token::RPAREN) {
3840 3841
        // allow the trailing comma
        break;
3842 3843 3844 3845
      }
    }
  }

3846 3847
  impl()->DeclareFormalParameters(parameters->scope, parameters->params,
                                  parameters->is_simple);
3848 3849
}

3850 3851 3852 3853
template <typename Impl>
typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseVariableDeclarations(
    VariableDeclarationContext var_context,
    DeclarationParsingResult* parsing_result,
3854
    ZonePtrList<const AstRawString>* names, bool* ok) {
3855 3856 3857 3858 3859 3860 3861
  // VariableDeclarations ::
  //   ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
  //
  // ES6:
  // FIXME(marja, nikolaos): Add an up-to-date comment about ES6 variable
  // declaration syntax.

3862
  DCHECK_NOT_NULL(parsing_result);
3863 3864 3865 3866
  parsing_result->descriptor.declaration_kind = DeclarationDescriptor::NORMAL;
  parsing_result->descriptor.declaration_pos = peek_position();
  parsing_result->descriptor.initialization_pos = peek_position();

3867
  BlockT init_block = impl()->NullStatement();
3868
  if (var_context != kForStatement) {
3869
    init_block = factory()->NewBlock(1, true);
3870 3871 3872 3873
  }

  switch (peek()) {
    case Token::VAR:
3874
      parsing_result->descriptor.mode = VariableMode::kVar;
3875 3876 3877 3878
      Consume(Token::VAR);
      break;
    case Token::CONST:
      Consume(Token::CONST);
3879
      DCHECK_NE(var_context, kStatement);
3880
      parsing_result->descriptor.mode = VariableMode::kConst;
3881 3882 3883
      break;
    case Token::LET:
      Consume(Token::LET);
3884
      DCHECK_NE(var_context, kStatement);
3885
      parsing_result->descriptor.mode = VariableMode::kLet;
3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898
      break;
    default:
      UNREACHABLE();  // by current callers
      break;
  }

  parsing_result->descriptor.scope = scope();

  int bindings_start = peek_position();
  do {
    // Parse binding pattern.
    FuncNameInferrer::State fni_state(fni_);

3899
    ExpressionT pattern = impl()->NullExpression();
3900 3901 3902
    int decl_pos = peek_position();
    {
      ExpressionClassifier pattern_classifier(this);
3903
      pattern = ParsePrimaryExpression(CHECK_OK_CUSTOM(NullStatement));
3904

3905
      ValidateBindingPattern(CHECK_OK_CUSTOM(NullStatement));
3906
      if (IsLexicalVariableMode(parsing_result->descriptor.mode)) {
3907
        ValidateLetPattern(CHECK_OK_CUSTOM(NullStatement));
3908 3909 3910 3911 3912 3913
      }
    }

    Scanner::Location variable_loc = scanner()->location();
    bool single_name = impl()->IsIdentifier(pattern);

3914 3915
    if (single_name) {
      impl()->PushVariableName(impl()->AsIdentifier(pattern));
3916 3917
    }

3918
    ExpressionT value = impl()->NullExpression();
3919
    int initializer_position = kNoSourcePosition;
3920
    int value_beg_position = kNoSourcePosition;
3921
    if (Check(Token::ASSIGN)) {
3922 3923
      value_beg_position = peek_position();

3924 3925
      ExpressionClassifier classifier(this);
      value = ParseAssignmentExpression(var_context != kForStatement,
3926
                                        CHECK_OK_CUSTOM(NullStatement));
3927
      ValidateExpression(CHECK_OK_CUSTOM(NullStatement));
3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949
      variable_loc.end_pos = scanner()->location().end_pos;

      if (!parsing_result->first_initializer_loc.IsValid()) {
        parsing_result->first_initializer_loc = variable_loc;
      }

      // Don't infer if it is "a = function(){...}();"-like expression.
      if (single_name && fni_ != nullptr) {
        if (!value->IsCall() && !value->IsCallNew()) {
          fni_->Infer();
        } else {
          fni_->RemoveLastFunction();
        }
      }

      impl()->SetFunctionNameFromIdentifierRef(value, pattern);

      // End position of the initializer is after the assignment expression.
      initializer_position = scanner()->location().end_pos;
    } else {
      if (var_context != kForStatement || !PeekInOrOf()) {
        // ES6 'const' and binding patterns require initializers.
3950
        if (parsing_result->descriptor.mode == VariableMode::kConst ||
3951 3952 3953 3954 3955 3956
            !impl()->IsIdentifier(pattern)) {
          impl()->ReportMessageAt(
              Scanner::Location(decl_pos, scanner()->location().end_pos),
              MessageTemplate::kDeclarationMissingInitializer,
              !impl()->IsIdentifier(pattern) ? "destructuring" : "const");
          *ok = false;
3957
          return impl()->NullStatement();
3958 3959
        }
        // 'let x' initializes 'x' to undefined.
3960
        if (parsing_result->descriptor.mode == VariableMode::kLet) {
3961
          value = factory()->NewUndefinedLiteral(position());
3962 3963 3964 3965 3966 3967 3968 3969 3970
        }
      }

      // End position of the initializer is after the variable.
      initializer_position = position();
    }

    typename DeclarationParsingResult::Declaration decl(
        pattern, initializer_position, value);
3971
    decl.value_beg_position = value_beg_position;
3972 3973
    if (var_context == kForStatement) {
      // Save the declaration for further handling in ParseForStatement.
3974
      parsing_result->declarations.push_back(decl);
3975 3976 3977 3978 3979
    } else {
      // Immediately declare the variable otherwise. This avoids O(N^2)
      // behavior (where N is the number of variables in a single
      // declaration) in the PatternRewriter having to do with removing
      // and adding VariableProxies to the Scope (see bug 4699).
3980 3981 3982
      impl()->DeclareAndInitializeVariables(
          init_block, &parsing_result->descriptor, &decl, names,
          CHECK_OK_CUSTOM(NullStatement));
3983 3984 3985 3986 3987 3988 3989 3990 3991 3992
    }
  } while (Check(Token::COMMA));

  parsing_result->bindings_loc =
      Scanner::Location(bindings_start, scanner()->location().end_pos);

  DCHECK(*ok);
  return init_block;
}

3993 3994 3995 3996 3997 3998 3999
template <typename Impl>
typename ParserBase<Impl>::StatementT
ParserBase<Impl>::ParseFunctionDeclaration(bool* ok) {
  Consume(Token::FUNCTION);
  int pos = position();
  ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal;
  if (Check(Token::MUL)) {
4000 4001 4002
    impl()->ReportMessageAt(
        scanner()->location(),
        MessageTemplate::kGeneratorInSingleStatementContext);
4003 4004
    *ok = false;
    return impl()->NullStatement();
4005 4006 4007 4008
  }
  return ParseHoistableDeclaration(pos, flags, nullptr, false, ok);
}

4009 4010 4011
template <typename Impl>
typename ParserBase<Impl>::StatementT
ParserBase<Impl>::ParseHoistableDeclaration(
4012
    ZonePtrList<const AstRawString>* names, bool default_export, bool* ok) {
4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024
  Expect(Token::FUNCTION, CHECK_OK_CUSTOM(NullStatement));
  int pos = position();
  ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal;
  if (Check(Token::MUL)) {
    flags |= ParseFunctionFlags::kIsGenerator;
  }
  return ParseHoistableDeclaration(pos, flags, names, default_export, ok);
}

template <typename Impl>
typename ParserBase<Impl>::StatementT
ParserBase<Impl>::ParseHoistableDeclaration(
4025
    int pos, ParseFunctionFlags flags, ZonePtrList<const AstRawString>* names,
4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037
    bool default_export, bool* ok) {
  // FunctionDeclaration ::
  //   'function' Identifier '(' FormalParameters ')' '{' FunctionBody '}'
  //   'function' '(' FormalParameters ')' '{' FunctionBody '}'
  // GeneratorDeclaration ::
  //   'function' '*' Identifier '(' FormalParameters ')' '{' FunctionBody '}'
  //   'function' '*' '(' FormalParameters ')' '{' FunctionBody '}'
  //
  // The anonymous forms are allowed iff [default_export] is true.
  //
  // 'function' and '*' (if present) have been consumed by the caller.

4038
  bool is_generator = flags & ParseFunctionFlags::kIsGenerator;
4039 4040 4041
  const bool is_async = flags & ParseFunctionFlags::kIsAsync;
  DCHECK(!is_generator || !is_async);

4042
  if (is_async && Check(Token::MUL)) {
4043 4044 4045 4046
    // Async generator
    is_generator = true;
  }

4047 4048 4049 4050 4051 4052 4053 4054
  IdentifierT name;
  FunctionNameValidity name_validity;
  IdentifierT variable_name;
  if (default_export && peek() == Token::LPAREN) {
    impl()->GetDefaultStrings(&name, &variable_name);
    name_validity = kSkipFunctionNameCheck;
  } else {
    bool is_strict_reserved;
4055 4056
    bool is_await = false;
    name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved, &is_await,
4057 4058 4059 4060 4061 4062 4063 4064
                                               CHECK_OK_CUSTOM(NullStatement));
    name_validity = is_strict_reserved ? kFunctionNameIsStrictReserved
                                       : kFunctionNameValidityUnknown;
    variable_name = name;
  }

  FuncNameInferrer::State fni_state(fni_);
  impl()->PushEnclosingName(name);
4065 4066 4067

  FunctionKind kind = FunctionKindFor(is_generator, is_async);

4068
  FunctionLiteralT function = impl()->ParseFunctionLiteral(
4069
      name, scanner()->location(), name_validity, kind, pos,
4070
      FunctionLiteral::kDeclaration, language_mode(), nullptr,
4071 4072
      CHECK_OK_CUSTOM(NullStatement));

4073 4074 4075
  // In ES6, a function behaves as a lexical binding, except in
  // a script scope, or the initial scope of eval or another function.
  VariableMode mode =
4076 4077 4078
      (!scope()->is_declaration_scope() || scope()->is_module_scope())
          ? VariableMode::kLet
          : VariableMode::kVar;
4079 4080 4081 4082 4083
  // Async functions don't undergo sloppy mode block scoped hoisting, and don't
  // allow duplicates in a block. Both are represented by the
  // sloppy_block_function_map. Don't add them to the map for async functions.
  // Generators are also supposed to be prohibited; currently doing this behind
  // a flag and UseCounting violations to assess web compatibility.
4084 4085 4086
  bool is_sloppy_block_function = is_sloppy(language_mode()) &&
                                  !scope()->is_declaration_scope() &&
                                  !is_async && !is_generator;
4087 4088 4089

  return impl()->DeclareFunction(variable_name, function, mode, pos,
                                 is_sloppy_block_function, names, ok);
4090 4091
}

4092 4093
template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseClassDeclaration(
4094
    ZonePtrList<const AstRawString>* names, bool default_export, bool* ok) {
4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113
  // ClassDeclaration ::
  //   'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}'
  //   'class' ('extends' LeftHandExpression)? '{' ClassBody '}'
  //
  // The anonymous form is allowed iff [default_export] is true.
  //
  // 'class' is expected to be consumed by the caller.
  //
  // A ClassDeclaration
  //
  //   class C { ... }
  //
  // has the same semantics as:
  //
  //   let C = class C { ... };
  //
  // so rewrite it as such.

  int class_token_pos = position();
4114
  IdentifierT name = impl()->NullIdentifier();
4115
  bool is_strict_reserved = false;
4116
  IdentifierT variable_name = impl()->NullIdentifier();
4117 4118 4119
  if (default_export && (peek() == Token::EXTENDS || peek() == Token::LBRACE)) {
    impl()->GetDefaultStrings(&name, &variable_name);
  } else {
4120 4121
    bool is_await = false;
    name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved, &is_await,
4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141
                                               CHECK_OK_CUSTOM(NullStatement));
    variable_name = name;
  }

  ExpressionClassifier no_classifier(this);
  ExpressionT value =
      ParseClassLiteral(name, scanner()->location(), is_strict_reserved,
                        class_token_pos, CHECK_OK_CUSTOM(NullStatement));
  int end_pos = position();
  return impl()->DeclareClass(variable_name, value, names, class_token_pos,
                              end_pos, ok);
}

// Language extension which is only enabled for source files loaded
// through the API's extension mechanism.  A native function
// declaration is resolved by looking up the function through a
// callback provided by the extension.
template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseNativeDeclaration(
    bool* ok) {
4142
  function_state_->DisableOptimization(BailoutReason::kNativeFunctionLiteral);
4143

4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160
  int pos = peek_position();
  Expect(Token::FUNCTION, CHECK_OK_CUSTOM(NullStatement));
  // Allow "eval" or "arguments" for backward compatibility.
  IdentifierT name = ParseIdentifier(kAllowRestrictedIdentifiers,
                                     CHECK_OK_CUSTOM(NullStatement));
  Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullStatement));
  if (peek() != Token::RPAREN) {
    do {
      ParseIdentifier(kAllowRestrictedIdentifiers,
                      CHECK_OK_CUSTOM(NullStatement));
    } while (Check(Token::COMMA));
  }
  Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullStatement));
  Expect(Token::SEMICOLON, CHECK_OK_CUSTOM(NullStatement));
  return impl()->DeclareNative(name, pos, ok);
}

4161 4162 4163
template <typename Impl>
typename ParserBase<Impl>::StatementT
ParserBase<Impl>::ParseAsyncFunctionDeclaration(
4164
    ZonePtrList<const AstRawString>* names, bool default_export, bool* ok) {
4165 4166 4167 4168 4169
  // AsyncFunctionDeclaration ::
  //   async [no LineTerminator here] function BindingIdentifier[Await]
  //       ( FormalParameters[Await] ) { AsyncFunctionBody }
  DCHECK_EQ(scanner()->current_token(), Token::ASYNC);
  int pos = position();
4170
  if (scanner()->HasLineTerminatorBeforeNext()) {
4171 4172 4173 4174 4175 4176 4177 4178 4179
    *ok = false;
    impl()->ReportUnexpectedToken(scanner()->current_token());
    return impl()->NullStatement();
  }
  Expect(Token::FUNCTION, CHECK_OK_CUSTOM(NullStatement));
  ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync;
  return ParseHoistableDeclaration(pos, flags, names, default_export, ok);
}

4180 4181 4182 4183 4184 4185 4186
template <typename Impl>
void ParserBase<Impl>::ParseFunctionBody(
    typename ParserBase<Impl>::StatementListT result, IdentifierT function_name,
    int pos, const FormalParametersT& parameters, FunctionKind kind,
    FunctionLiteral::FunctionType function_type, bool* ok) {
  DeclarationScope* function_scope = scope()->AsDeclarationScope();
  DeclarationScope* inner_scope = function_scope;
4187
  BlockT inner_block = impl()->NullStatement();
4188 4189 4190 4191 4192

  StatementListT body = result;
  if (!parameters.is_simple) {
    inner_scope = NewVarblockScope();
    inner_scope->set_start_position(scanner()->location().beg_pos);
4193
    inner_block = factory()->NewBlock(8, true);
4194 4195 4196 4197
    inner_block->set_scope(inner_scope);
    body = inner_block->statements();
  }

4198 4199 4200 4201 4202
  // If we are parsing the source as if it is wrapped in a function, the source
  // ends without a closing brace.
  Token::Value closing_token =
      function_type == FunctionLiteral::kWrapped ? Token::EOS : Token::RBRACE;

4203
  {
4204
    BlockState block_state(&scope_, inner_scope);
4205

4206 4207
    if (IsResumableFunction(kind)) impl()->PrepareGeneratorVariables();

4208 4209 4210
    if (IsAsyncGeneratorFunction(kind)) {
      impl()->ParseAndRewriteAsyncGeneratorFunctionBody(pos, kind, body, ok);
    } else if (IsGeneratorFunction(kind)) {
4211 4212
      impl()->ParseAndRewriteGeneratorFunctionBody(pos, kind, body, ok);
    } else if (IsAsyncFunction(kind)) {
4213
      ParseAsyncFunctionBody(inner_scope, body, CHECK_OK_VOID);
4214
    } else {
4215
      ParseStatementList(body, closing_token, CHECK_OK_VOID);
4216 4217 4218 4219 4220 4221 4222 4223 4224
    }

    if (IsDerivedConstructor(kind)) {
      body->Add(factory()->NewReturnStatement(impl()->ThisExpression(),
                                              kNoSourcePosition),
                zone());
    }
  }

4225
  Expect(closing_token, CHECK_OK_VOID);
4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240
  scope()->set_end_position(scanner()->location().end_pos);

  if (!parameters.is_simple) {
    DCHECK_NOT_NULL(inner_scope);
    DCHECK_EQ(function_scope, scope());
    DCHECK_EQ(function_scope, inner_scope->outer_scope());
    impl()->SetLanguageMode(function_scope, inner_scope->language_mode());
    BlockT init_block =
        impl()->BuildParameterInitializationBlock(parameters, CHECK_OK_VOID);

    if (is_sloppy(inner_scope->language_mode())) {
      impl()->InsertSloppyBlockFunctionVarBindings(inner_scope);
    }

    // TODO(littledan): Merge the two rejection blocks into one
4241
    if (IsAsyncFunction(kind) && !IsAsyncGeneratorFunction(kind)) {
4242 4243 4244 4245 4246 4247 4248
      init_block = impl()->BuildRejectPromiseOnException(init_block);
    }

    inner_scope->set_end_position(scanner()->location().end_pos);
    if (inner_scope->FinalizeBlockScope() != nullptr) {
      impl()->CheckConflictingVarDeclarations(inner_scope, CHECK_OK_VOID);
      impl()->InsertShadowingVarBindingInitializers(inner_block);
4249 4250
    } else {
      inner_block->set_scope(nullptr);
4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269
    }
    inner_scope = nullptr;

    result->Add(init_block, zone());
    result->Add(inner_block, zone());
  } else {
    DCHECK_EQ(inner_scope, function_scope);
    if (is_sloppy(function_scope->language_mode())) {
      impl()->InsertSloppyBlockFunctionVarBindings(function_scope);
    }
  }

  if (!IsArrowFunction(kind)) {
    // Declare arguments after parsing the function since lexical 'arguments'
    // masks the arguments object. Declare arguments before declaring the
    // function var since the arguments object masks 'function arguments'.
    function_scope->DeclareArguments(ast_value_factory());
  }

4270
  impl()->DeclareFunctionNameVar(function_name, function_type, function_scope);
4271 4272
}

4273 4274 4275 4276 4277 4278
template <typename Impl>
void ParserBase<Impl>::CheckArityRestrictions(int param_count,
                                              FunctionKind function_kind,
                                              bool has_rest,
                                              int formals_start_pos,
                                              int formals_end_pos, bool* ok) {
4279 4280
  if (IsGetterFunction(function_kind)) {
    if (param_count != 0) {
4281 4282 4283
      impl()->ReportMessageAt(
          Scanner::Location(formals_start_pos, formals_end_pos),
          MessageTemplate::kBadGetterArity);
4284 4285 4286 4287
      *ok = false;
    }
  } else if (IsSetterFunction(function_kind)) {
    if (param_count != 1) {
4288 4289 4290
      impl()->ReportMessageAt(
          Scanner::Location(formals_start_pos, formals_end_pos),
          MessageTemplate::kBadSetterArity);
4291 4292 4293
      *ok = false;
    }
    if (has_rest) {
4294 4295 4296
      impl()->ReportMessageAt(
          Scanner::Location(formals_start_pos, formals_end_pos),
          MessageTemplate::kBadSetterRestParameter);
4297 4298
      *ok = false;
    }
4299 4300 4301
  }
}

4302 4303
template <typename Impl>
bool ParserBase<Impl>::IsNextLetKeyword() {
4304
  DCHECK_EQ(Token::LET, peek());
4305 4306 4307 4308 4309 4310
  Token::Value next_next = PeekAhead();
  switch (next_next) {
    case Token::LBRACE:
    case Token::LBRACK:
    case Token::IDENTIFIER:
    case Token::STATIC:
4311 4312 4313 4314 4315
    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.
4316 4317
    case Token::YIELD:
    case Token::AWAIT:
4318
    case Token::ASYNC:
4319
      return true;
4320 4321
    case Token::FUTURE_STRICT_RESERVED_WORD:
      return is_sloppy(language_mode());
4322 4323 4324 4325 4326
    default:
      return false;
  }
}

4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340
template <typename Impl>
bool ParserBase<Impl>::IsTrivialExpression() {
  if (Token::IsTrivialExpressionToken(peek())) {
    // PeekAhead() may not always be called, so we only call it after checking
    // peek().
    Token::Value peek_ahead = PeekAhead();
    if (peek_ahead == Token::COMMA || peek_ahead == Token::RPAREN ||
        peek_ahead == Token::SEMICOLON || peek_ahead == Token::RBRACK) {
      return true;
    }
  }
  return false;
}

4341 4342 4343
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseArrowFunctionLiteral(
4344 4345
    bool accept_IN, const FormalParametersT& formal_parameters,
    int rewritable_length, bool* ok) {
4346 4347 4348 4349 4350
  const RuntimeCallCounterId counters[2][2] = {
      {RuntimeCallCounterId::kParseBackgroundArrowFunctionLiteral,
       RuntimeCallCounterId::kParseArrowFunctionLiteral},
      {RuntimeCallCounterId::kPreParseBackgroundArrowFunctionLiteral,
       RuntimeCallCounterId::kPreParseArrowFunctionLiteral}};
4351 4352
  RuntimeCallTimerScope runtime_timer(
      runtime_call_stats_,
4353
      counters[Impl::IsPreParser()][parsing_on_main_thread_]);
4354 4355
  base::ElapsedTimer timer;
  if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();
4356

4357
  if (peek() == Token::ARROW && scanner_->HasLineTerminatorBeforeNext()) {
4358 4359 4360 4361 4362
    // ASI inserts `;` after arrow parameters if a line terminator is found.
    // `=> ...` is never a valid expression, so report as syntax error.
    // If next token is not `=>`, it's a syntax error anyways.
    ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW);
    *ok = false;
4363
    return impl()->NullExpression();
4364 4365
  }

4366
  StatementListT body = impl()->NullStatementList();
4367
  int expected_property_count = -1;
4368
  int suspend_count = 0;
4369
  int function_literal_id = GetNextFunctionLiteralId();
4370

4371
  FunctionKind kind = formal_parameters.scope->function_kind();
4372
  FunctionLiteral::EagerCompileHint eager_compile_hint =
4373
      default_eager_compile_hint_;
4374
  bool can_preparse = impl()->parse_lazily() &&
4375 4376 4377 4378
                      eager_compile_hint == FunctionLiteral::kShouldLazyCompile;
  // TODO(marja): consider lazy-parsing inner arrow functions too. is_this
  // handling in Scope::ResolveVariable needs to change.
  bool is_lazy_top_level_function =
4379
      can_preparse && impl()->AllowsLazyParsingWithoutUnresolvedVariables();
4380
  bool has_braces = true;
4381
  ProducedPreParsedScopeData* produced_preparsed_scope_data = nullptr;
4382
  {
4383
    FunctionState function_state(&function_state_, &scope_,
4384
                                 formal_parameters.scope);
4385

4386 4387 4388 4389 4390
    // Move any queued destructuring assignments which appeared
    // in this function's parameter list into its own function_state.
    function_state.AdoptDestructuringAssignmentsFromParentState(
        rewritable_length);

4391 4392 4393 4394
    Expect(Token::ARROW, CHECK_OK);

    if (peek() == Token::LBRACE) {
      // Multiple statement body
4395
      DCHECK_EQ(scope(), formal_parameters.scope);
4396
      if (is_lazy_top_level_function) {
4397 4398 4399
        // FIXME(marja): Arrow function parameters will be parsed even if the
        // body is preparsed; move relevant parts of parameter handling to
        // simulate consistent parameter handling.
4400

4401 4402 4403
        // For arrow functions, we don't need to retrieve data about function
        // parameters.
        int dummy_num_parameters = -1;
4404
        DCHECK_NE(kind & FunctionKind::kArrowFunction, 0);
4405 4406
        LazyParsingResult result = impl()->SkipFunction(
            nullptr, kind, FunctionLiteral::kAnonymousExpression,
4407 4408
            formal_parameters.scope, &dummy_num_parameters,
            &produced_preparsed_scope_data, false, false, CHECK_OK);
4409
        DCHECK_NE(result, kLazyParsingAborted);
4410
        DCHECK_NULL(produced_preparsed_scope_data);
4411 4412 4413
        USE(result);
        formal_parameters.scope->ResetAfterPreparsing(ast_value_factory_,
                                                      false);
4414
        // Discard any queued destructuring assignments which appeared
4415 4416 4417
        // in this function's parameter list, and which were adopted
        // into this function state, above.
        function_state.RewindDestructuringAssignments(0);
4418
      } else {
4419
        Consume(Token::LBRACE);
4420
        body = impl()->NewStatementList(8);
4421
        ParseFunctionBody(body, impl()->NullIdentifier(), kNoSourcePosition,
4422 4423
                          formal_parameters, kind,
                          FunctionLiteral::kAnonymousExpression, CHECK_OK);
4424 4425 4426 4427
        expected_property_count = function_state.expected_property_count();
      }
    } else {
      // Single-expression body
4428
      has_braces = false;
4429
      const bool is_async = IsAsyncFunction(kind);
4430
      body = impl()->NewStatementList(1);
4431 4432 4433
      impl()->AddParameterInitializationBlock(formal_parameters, body, is_async,
                                              CHECK_OK);
      ParseSingleExpressionFunctionBody(body, is_async, accept_IN, CHECK_OK);
4434 4435 4436 4437 4438 4439 4440 4441 4442 4443
      expected_property_count = function_state.expected_property_count();
    }

    formal_parameters.scope->set_end_position(scanner()->location().end_pos);

    // Arrow function formal parameters are parsed as StrictFormalParameterList,
    // which is not the same as "parameters of a strict function"; it only means
    // that duplicates are not allowed.  Of course, the arrow function may
    // itself be strict as well.
    const bool allow_duplicate_parameters = false;
4444 4445
    ValidateFormalParameters(language_mode(), allow_duplicate_parameters,
                             CHECK_OK);
4446 4447 4448 4449 4450 4451

    // Validate strict mode.
    if (is_strict(language_mode())) {
      CheckStrictOctalLiteral(formal_parameters.scope->start_position(),
                              scanner()->location().end_pos, CHECK_OK);
    }
4452
    impl()->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK);
4453

4454
    impl()->RewriteDestructuringAssignments();
4455
    suspend_count = function_state.suspend_count();
4456 4457 4458
  }

  FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
4459
      impl()->EmptyIdentifierString(), formal_parameters.scope, body,
4460 4461
      expected_property_count, formal_parameters.num_parameters(),
      formal_parameters.function_length,
4462
      FunctionLiteral::kNoDuplicateParameters,
4463
      FunctionLiteral::kAnonymousExpression, eager_compile_hint,
4464
      formal_parameters.scope->start_position(), has_braces,
4465
      function_literal_id, produced_preparsed_scope_data);
4466

4467
  function_literal->set_suspend_count(suspend_count);
4468 4469 4470
  function_literal->set_function_token_position(
      formal_parameters.scope->start_position());

4471
  impl()->AddFunctionForNameInference(function_literal);
4472

4473 4474 4475 4476 4477 4478
  if (V8_UNLIKELY((FLAG_log_function_events))) {
    Scope* scope = formal_parameters.scope;
    double ms = timer.Elapsed().InMillisecondsF();
    const char* event_name =
        is_lazy_top_level_function ? "preparse-no-resolution" : "parse";
    const char* name = "arrow function";
4479 4480
    logger_->FunctionEvent(event_name, script_id(), ms, scope->start_position(),
                           scope->end_position(), name, strlen(name));
4481 4482
  }

4483 4484 4485
  return function_literal;
}

4486 4487 4488 4489
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseClassLiteral(
    IdentifierT name, Scanner::Location class_name_location,
    bool name_is_strict_reserved, int class_token_pos, bool* ok) {
4490
  bool is_anonymous = impl()->IsNull(name);
4491

4492
  // All parts of a ClassDeclaration and ClassExpression are strict code.
4493 4494 4495 4496 4497
  if (!is_anonymous) {
    if (name_is_strict_reserved) {
      impl()->ReportMessageAt(class_name_location,
                              MessageTemplate::kUnexpectedStrictReserved);
      *ok = false;
4498
      return impl()->NullExpression();
4499 4500 4501 4502 4503
    }
    if (impl()->IsEvalOrArguments(name)) {
      impl()->ReportMessageAt(class_name_location,
                              MessageTemplate::kStrictEvalArguments);
      *ok = false;
4504
      return impl()->NullExpression();
4505
    }
4506 4507
  }

4508 4509
  Scope* block_scope = NewScope(BLOCK_SCOPE);
  BlockState block_state(&scope_, block_scope);
4510
  RaiseLanguageMode(LanguageMode::kStrict);
4511 4512

  ClassInfo class_info(this);
4513
  class_info.is_anonymous = is_anonymous;
4514
  impl()->DeclareClassVariable(name, &class_info, class_token_pos, CHECK_OK);
4515

4516
  scope()->set_start_position(scanner()->location().end_pos);
4517
  if (Check(Token::EXTENDS)) {
4518
    FuncNameInferrer::State fni_state(fni_);
4519 4520
    ExpressionClassifier extends_classifier(this);
    class_info.extends = ParseLeftHandSideExpression(CHECK_OK);
4521
    ValidateExpression(CHECK_OK);
4522
    AccumulateFormalParameterContainmentErrors();
4523 4524 4525 4526 4527 4528
  }

  ClassLiteralChecker checker(this);

  Expect(Token::LBRACE, CHECK_OK);

4529
  const bool has_extends = !impl()->IsNull(class_info.extends);
4530 4531 4532 4533 4534
  while (peek() != Token::RBRACE) {
    if (Check(Token::SEMICOLON)) continue;
    FuncNameInferrer::State fni_state(fni_);
    bool is_computed_name = false;  // Classes do not care about computed
                                    // property names here.
4535 4536
    bool is_static;
    ClassLiteralProperty::Kind property_kind;
4537
    ExpressionClassifier property_classifier(this);
4538
    IdentifierT property_name;
4539 4540 4541
    // If we haven't seen the constructor yet, it potentially is the next
    // property.
    bool is_constructor = !class_info.has_seen_constructor;
4542
    ClassLiteralPropertyT property = ParseClassPropertyDefinition(
4543
        &checker, &class_info, &property_name, has_extends, &is_computed_name,
4544
        &property_kind, &is_static, CHECK_OK);
4545 4546 4547 4548
    if (!class_info.has_static_computed_names && is_static &&
        is_computed_name) {
      class_info.has_static_computed_names = true;
    }
4549 4550
    if (is_computed_name &&
        property_kind == ClassLiteralProperty::PUBLIC_FIELD) {
4551 4552
      class_info.computed_field_count++;
    }
4553
    is_constructor &= class_info.has_seen_constructor;
4554
    ValidateExpression(CHECK_OK);
4555
    AccumulateFormalParameterContainmentErrors();
4556

4557 4558 4559
    impl()->DeclareClassProperty(name, property, property_name, property_kind,
                                 is_static, is_constructor, is_computed_name,
                                 &class_info, CHECK_OK);
4560 4561 4562 4563
    impl()->InferFunctionName();
  }

  Expect(Token::RBRACE, CHECK_OK);
4564 4565
  int end_pos = scanner()->location().end_pos;
  block_scope->set_end_position(end_pos);
4566
  return impl()->RewriteClassLiteral(block_scope, name, &class_info,
4567
                                     class_token_pos, end_pos, ok);
4568 4569
}

4570
template <typename Impl>
4571 4572 4573 4574 4575
void ParserBase<Impl>::ParseSingleExpressionFunctionBody(StatementListT body,
                                                         bool is_async,
                                                         bool accept_IN,
                                                         bool* ok) {
  if (is_async) impl()->PrepareGeneratorVariables();
4576

4577 4578
  ExpressionClassifier classifier(this);
  ExpressionT expression = ParseAssignmentExpression(accept_IN, CHECK_OK_VOID);
4579
  ValidateExpression(CHECK_OK_VOID);
4580

4581
  if (is_async) {
4582
    BlockT block = factory()->NewBlock(1, true);
4583
    impl()->RewriteAsyncFunctionBody(body, block, expression, CHECK_OK_VOID);
4584
  } else {
4585
    body->Add(BuildReturnStatement(expression, expression->position()), zone());
4586
  }
4587 4588 4589 4590 4591
}

template <typename Impl>
void ParserBase<Impl>::ParseAsyncFunctionBody(Scope* scope, StatementListT body,
                                              bool* ok) {
4592
  BlockT block = factory()->NewBlock(8, true);
4593

4594 4595 4596 4597
  ParseStatementList(block->statements(), Token::RBRACE, CHECK_OK_VOID);
  impl()->RewriteAsyncFunctionBody(
      body, block, factory()->NewUndefinedLiteral(kNoSourcePosition),
      CHECK_OK_VOID);
4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613
  scope->set_end_position(scanner()->location().end_pos);
}

template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseAsyncFunctionLiteral(bool* ok) {
  // AsyncFunctionLiteral ::
  //   async [no LineTerminator here] function ( FormalParameters[Await] )
  //       { AsyncFunctionBody }
  //
  //   async [no LineTerminator here] function BindingIdentifier[Await]
  //       ( FormalParameters[Await] ) { AsyncFunctionBody }
  DCHECK_EQ(scanner()->current_token(), Token::ASYNC);
  int pos = position();
  Expect(Token::FUNCTION, CHECK_OK);
  bool is_strict_reserved = false;
4614
  IdentifierT name = impl()->NullIdentifier();
4615 4616
  FunctionLiteral::FunctionType type = FunctionLiteral::kAnonymousExpression;

4617
  bool is_generator = Check(Token::MUL);
4618
  const bool kIsAsync = true;
4619
  const FunctionKind kind = FunctionKindFor(is_generator, kIsAsync);
4620

4621 4622 4623
  if (impl()->ParsingDynamicFunctionDeclaration()) {
    // We don't want dynamic functions to actually declare their name
    // "anonymous". We just want that name in the toString().
4624 4625
    if (stack_overflow()) {
      *ok = false;
4626
      return impl()->NullExpression();
4627
    }
4628
    Consume(Token::IDENTIFIER);
4629
    DCHECK(scanner()->CurrentMatchesContextual(Token::ANONYMOUS));
4630
  } else if (peek_any_identifier()) {
4631
    type = FunctionLiteral::kNamedExpression;
4632
    bool is_await = false;
4633
    name = ParseIdentifierOrStrictReservedWord(kind, &is_strict_reserved,
4634 4635 4636 4637
                                               &is_await, CHECK_OK);
    // If the function name is "await", ParseIdentifierOrStrictReservedWord
    // recognized the error.
    DCHECK(!is_await);
4638 4639 4640 4641 4642
  }
  return impl()->ParseFunctionLiteral(
      name, scanner()->location(),
      is_strict_reserved ? kFunctionNameIsStrictReserved
                         : kFunctionNameValidityUnknown,
4643
      kind, pos, type, language_mode(), nullptr, CHECK_OK);
4644 4645
}

4646 4647
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral(
4648
    ExpressionT tag, int start, bool tagged, bool* ok) {
4649 4650 4651 4652 4653 4654 4655 4656 4657 4658
  // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal
  // text followed by a substitution expression), finalized by a single
  // TEMPLATE_TAIL.
  //
  // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or
  // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or
  // NoSubstitutionTemplate.
  //
  // When parsing a TemplateLiteral, we must have scanned either an initial
  // TEMPLATE_SPAN, or a TEMPLATE_TAIL.
4659
  DCHECK(peek() == Token::TEMPLATE_SPAN || peek() == Token::TEMPLATE_TAIL);
4660

4661 4662 4663 4664 4665 4666
  if (tagged) {
    // TaggedTemplate expressions prevent the eval compilation cache from being
    // used. This flag is only used if an eval is being parsed.
    set_allow_eval_cache(false);
  }

4667
  bool forbid_illegal_escapes = !tagged;
4668

4669 4670 4671 4672 4673 4674
  // If we reach a TEMPLATE_TAIL first, we are parsing a NoSubstitutionTemplate.
  // In this case we may simply consume the token and build a template with a
  // single TEMPLATE_SPAN and no expressions.
  if (peek() == Token::TEMPLATE_TAIL) {
    Consume(Token::TEMPLATE_TAIL);
    int pos = position();
4675
    typename Impl::TemplateLiteralState ts = impl()->OpenTemplateLiteral(pos);
4676 4677
    bool is_valid = CheckTemplateEscapes(forbid_illegal_escapes, CHECK_OK);
    impl()->AddTemplateSpan(&ts, is_valid, true);
4678
    return impl()->CloseTemplateLiteral(&ts, start, tag);
4679 4680 4681 4682
  }

  Consume(Token::TEMPLATE_SPAN);
  int pos = position();
4683
  typename Impl::TemplateLiteralState ts = impl()->OpenTemplateLiteral(pos);
4684 4685
  bool is_valid = CheckTemplateEscapes(forbid_illegal_escapes, CHECK_OK);
  impl()->AddTemplateSpan(&ts, is_valid, false);
4686 4687 4688 4689 4690 4691 4692 4693 4694
  Token::Value next;

  // If we open with a TEMPLATE_SPAN, we must scan the subsequent expression,
  // and repeat if the following token is a TEMPLATE_SPAN as well (in this
  // case, representing a TemplateMiddle).

  do {
    next = peek();
    if (next == Token::EOS) {
4695 4696
      impl()->ReportMessageAt(Scanner::Location(start, peek_position()),
                              MessageTemplate::kUnterminatedTemplate);
4697
      *ok = false;
4698
      return impl()->NullExpression();
4699
    } else if (next == Token::ILLEGAL) {
4700
      impl()->ReportMessageAt(
4701 4702 4703
          Scanner::Location(position() + 1, peek_position()),
          MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError);
      *ok = false;
4704
      return impl()->NullExpression();
4705 4706 4707
    }

    int expr_pos = peek_position();
4708
    ExpressionT expression = ParseExpressionCoverGrammar(true, CHECK_OK);
4709
    ValidateExpression(CHECK_OK);
4710
    impl()->AddTemplateExpression(&ts, expression);
4711 4712

    if (peek() != Token::RBRACE) {
4713 4714
      impl()->ReportMessageAt(Scanner::Location(expr_pos, peek_position()),
                              MessageTemplate::kUnterminatedTemplateExpr);
4715
      *ok = false;
4716
      return impl()->NullExpression();
4717 4718 4719 4720 4721 4722 4723 4724 4725
    }

    // If we didn't die parsing that expression, our next token should be a
    // TEMPLATE_SPAN or TEMPLATE_TAIL.
    next = scanner()->ScanTemplateContinuation();
    Next();
    pos = position();

    if (next == Token::EOS) {
4726 4727
      impl()->ReportMessageAt(Scanner::Location(start, pos),
                              MessageTemplate::kUnterminatedTemplate);
4728
      *ok = false;
4729
      return impl()->NullExpression();
4730
    } else if (next == Token::ILLEGAL) {
4731
      impl()->ReportMessageAt(
4732 4733 4734
          Scanner::Location(position() + 1, peek_position()),
          MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError);
      *ok = false;
4735
      return impl()->NullExpression();
4736 4737
    }

4738 4739
    bool is_valid = CheckTemplateEscapes(forbid_illegal_escapes, CHECK_OK);
    impl()->AddTemplateSpan(&ts, is_valid, next == Token::TEMPLATE_TAIL);
4740 4741 4742 4743
  } while (next == Token::TEMPLATE_SPAN);

  DCHECK_EQ(next, Token::TEMPLATE_TAIL);
  // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral.
4744
  return impl()->CloseTemplateLiteral(&ts, start, tag);
4745 4746
}

4747 4748 4749
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::CheckAndRewriteReferenceExpression(
4750 4751
    ExpressionT expression, int beg_pos, int end_pos,
    MessageTemplate::Template message, bool* ok) {
4752 4753
  return CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos,
                                            message, kReferenceError, ok);
4754 4755
}

4756 4757 4758
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::CheckAndRewriteReferenceExpression(
4759 4760
    ExpressionT expression, int beg_pos, int end_pos,
    MessageTemplate::Template message, ParseErrorType type, bool* ok) {
4761 4762
  if (impl()->IsIdentifier(expression) && is_strict(language_mode()) &&
      impl()->IsEvalOrArguments(impl()->AsIdentifier(expression))) {
4763 4764 4765
    ReportMessageAt(Scanner::Location(beg_pos, end_pos),
                    MessageTemplate::kStrictEvalArguments, kSyntaxError);
    *ok = false;
4766
    return impl()->NullExpression();
4767 4768 4769
  }
  if (expression->IsValidReferenceExpression()) {
    return expression;
4770
  }
4771
  if (expression->IsCall() && !expression->AsCall()->is_tagged_template()) {
4772
    // If it is a call, make it a runtime error for legacy web compatibility.
4773
    // Bug: https://bugs.chromium.org/p/v8/issues/detail?id=4480
4774
    // Rewrite `expr' to `expr[throw ReferenceError]'.
4775 4776 4777 4778
    impl()->CountUsage(
        is_strict(language_mode())
            ? v8::Isolate::kAssigmentExpressionLHSIsCallInStrict
            : v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy);
4779
    ExpressionT error = impl()->NewThrowReferenceError(message, beg_pos);
4780
    return factory()->NewProperty(expression, error, beg_pos);
4781
  }
4782 4783
  ReportMessageAt(Scanner::Location(beg_pos, end_pos), message, type);
  *ok = false;
4784
  return impl()->NullExpression();
4785 4786
}

4787 4788
template <typename Impl>
bool ParserBase<Impl>::IsValidReferenceExpression(ExpressionT expression) {
4789
  return IsAssignableIdentifier(expression) || expression->IsProperty();
4790 4791
}

4792
template <typename Impl>
4793 4794
void ParserBase<Impl>::CheckDestructuringElement(ExpressionT expression,
                                                 int begin, int end) {
4795
  if (!IsValidPattern(expression) && !expression->IsAssignment() &&
4796
      !IsValidReferenceExpression(expression)) {
4797
    classifier()->RecordAssignmentPatternError(
4798 4799
        Scanner::Location(begin, end),
        MessageTemplate::kInvalidDestructuringTarget);
4800
  }
4801 4802
}

4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseV8Intrinsic(
    bool* ok) {
  // CallRuntime ::
  //   '%' Identifier Arguments

  int pos = peek_position();
  Expect(Token::MOD, CHECK_OK);
  // Allow "eval" or "arguments" for backward compatibility.
  IdentifierT name = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
  Scanner::Location spread_pos;
  ExpressionClassifier classifier(this);
  ExpressionListT args = ParseArguments(&spread_pos, CHECK_OK);

4817 4818 4819 4820 4821 4822
  if (spread_pos.IsValid()) {
    *ok = false;
    ReportMessageAt(spread_pos, MessageTemplate::kIntrinsicWithSpread,
                    kSyntaxError);
    return impl()->NullExpression();
  }
4823 4824 4825 4826

  return impl()->NewV8Intrinsic(name, args, pos, ok);
}

4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseDoExpression(
    bool* ok) {
  // AssignmentExpression ::
  //     do '{' StatementList '}'

  int pos = peek_position();
  Expect(Token::DO, CHECK_OK);
  BlockT block = ParseBlock(nullptr, CHECK_OK);
  return impl()->RewriteDoExpression(block, pos, ok);
}

4839 4840 4841 4842 4843 4844
// Redefinition of CHECK_OK for parsing statements.
#undef CHECK_OK
#define CHECK_OK CHECK_OK_CUSTOM(NullStatement)

template <typename Impl>
typename ParserBase<Impl>::LazyParsingResult
4845 4846 4847
ParserBase<Impl>::ParseStatementList(StatementListT body,
                                     Token::Value end_token, bool may_abort,
                                     bool* ok) {
4848 4849 4850 4851 4852 4853 4854 4855 4856 4857
  // StatementList ::
  //   (StatementListItem)* <end_token>

  // Allocate a target stack to use for this set of source
  // elements. This way, all scripts and functions get their own
  // target stack thus avoiding illegal breaks and continues across
  // functions.
  typename Types::TargetScope target_scope(this);
  int count_statements = 0;

4858
  DCHECK(!impl()->IsNull(body));
4859 4860 4861 4862 4863 4864 4865 4866 4867
  bool directive_prologue = true;  // Parsing directive prologue.

  while (peek() != end_token) {
    if (directive_prologue && peek() != Token::STRING) {
      directive_prologue = false;
    }

    bool starts_with_identifier = peek() == Token::IDENTIFIER;
    Scanner::Location token_loc = scanner()->peek_location();
4868 4869
    StatementT stat =
        ParseStatementListItem(CHECK_OK_CUSTOM(Return, kLazyParsingComplete));
4870

4871
    if (impl()->IsNull(stat) || stat->IsEmptyStatement()) {
4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883
      directive_prologue = false;  // End of directive prologue.
      continue;
    }

    if (directive_prologue) {
      // The length of the token is used to distinguish between strings literals
      // that evaluate equal to directives but contain either escape sequences
      // (e.g., "use \x73trict") or line continuations (e.g., "use \(newline)
      // strict").
      if (impl()->IsUseStrictDirective(stat) &&
          token_loc.end_pos - token_loc.beg_pos == sizeof("use strict") + 1) {
        // Directive "use strict" (ES5 14.1).
4884
        RaiseLanguageMode(LanguageMode::kStrict);
4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901
        if (!scope()->HasSimpleParameters()) {
          // TC39 deemed "use strict" directives to be an error when occurring
          // in the body of a function with non-simple parameter list, on
          // 29/7/2015. https://goo.gl/ueA7Ln
          impl()->ReportMessageAt(
              token_loc, MessageTemplate::kIllegalLanguageModeDirective,
              "use strict");
          *ok = false;
          return kLazyParsingComplete;
        }
      } else if (impl()->IsUseAsmDirective(stat) &&
                 token_loc.end_pos - token_loc.beg_pos ==
                     sizeof("use asm") + 1) {
        // Directive "use asm".
        impl()->SetAsmModule();
      } else if (impl()->IsStringLiteral(stat)) {
        // Possibly an unknown directive.
4902 4903
        // Should not change mode, but will increment usage counters
        // as appropriate. Ditto usages below.
4904
        RaiseLanguageMode(LanguageMode::kSloppy);
4905 4906 4907
      } else {
        // End of the directive prologue.
        directive_prologue = false;
4908
        RaiseLanguageMode(LanguageMode::kSloppy);
4909 4910
      }
    } else {
4911
      RaiseLanguageMode(LanguageMode::kSloppy);
4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952
    }

    // If we're allowed to abort, we will do so when we see a "long and
    // trivial" function. Our current definition of "long and trivial" is:
    // - over kLazyParseTrialLimit statements
    // - all starting with an identifier (i.e., no if, for, while, etc.)
    if (may_abort) {
      if (!starts_with_identifier) {
        may_abort = false;
      } else if (++count_statements > kLazyParseTrialLimit) {
        return kLazyParsingAborted;
      }
    }

    body->Add(stat, zone());
  }
  return kLazyParsingComplete;
}

template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseStatementListItem(
    bool* ok) {
  // ECMA 262 6th Edition
  // StatementListItem[Yield, Return] :
  //   Statement[?Yield, ?Return]
  //   Declaration[?Yield]
  //
  // Declaration[Yield] :
  //   HoistableDeclaration[?Yield]
  //   ClassDeclaration[?Yield]
  //   LexicalDeclaration[In, ?Yield]
  //
  // HoistableDeclaration[Yield, Default] :
  //   FunctionDeclaration[?Yield, ?Default]
  //   GeneratorDeclaration[?Yield, ?Default]
  //
  // LexicalDeclaration[In, Yield] :
  //   LetOrConst BindingList[?In, ?Yield] ;

  switch (peek()) {
    case Token::FUNCTION:
4953
      return ParseHoistableDeclaration(nullptr, false, ok);
4954 4955
    case Token::CLASS:
      Consume(Token::CLASS);
4956
      return ParseClassDeclaration(nullptr, false, ok);
4957 4958
    case Token::VAR:
    case Token::CONST:
4959
      return ParseVariableStatement(kStatementListItem, nullptr, ok);
4960 4961
    case Token::LET:
      if (IsNextLetKeyword()) {
4962
        return ParseVariableStatement(kStatementListItem, nullptr, ok);
4963 4964 4965
      }
      break;
    case Token::ASYNC:
4966
      if (PeekAhead() == Token::FUNCTION &&
4967
          !scanner()->HasLineTerminatorAfterNext()) {
4968
        Consume(Token::ASYNC);
4969
        return ParseAsyncFunctionDeclaration(nullptr, false, ok);
4970
      }
4971
      break;
4972 4973 4974
    default:
      break;
  }
4975
  return ParseStatement(nullptr, nullptr, kAllowLabelledFunctionStatement, ok);
4976 4977 4978 4979
}

template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseStatement(
4980
    ZonePtrList<const AstRawString>* labels,
4981
    ZonePtrList<const AstRawString>* own_labels,
4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999
    AllowLabelledFunctionStatement allow_function, bool* ok) {
  // Statement ::
  //   Block
  //   VariableStatement
  //   EmptyStatement
  //   ExpressionStatement
  //   IfStatement
  //   IterationStatement
  //   ContinueStatement
  //   BreakStatement
  //   ReturnStatement
  //   WithStatement
  //   LabelledStatement
  //   SwitchStatement
  //   ThrowStatement
  //   TryStatement
  //   DebuggerStatement

5000 5001 5002
  // {own_labels} is always a subset of {labels}.
  DCHECK_IMPLIES(labels == nullptr, own_labels == nullptr);

5003 5004 5005 5006 5007 5008 5009 5010
  // Note: Since labels can only be used by 'break' and 'continue'
  // statements, which themselves are only valid within blocks,
  // iterations or 'switch' statements (i.e., BreakableStatements),
  // labels can be simply ignored in all other cases; except for
  // trivial labeled break statements 'label: break label' which is
  // parsed into an empty statement.
  switch (peek()) {
    case Token::LBRACE:
5011
      return ParseBlock(labels, ok);
5012 5013 5014 5015
    case Token::SEMICOLON:
      Next();
      return factory()->NewEmptyStatement(kNoSourcePosition);
    case Token::IF:
5016
      return ParseIfStatement(labels, ok);
5017
    case Token::DO:
5018
      return ParseDoWhileStatement(labels, own_labels, ok);
5019
    case Token::WHILE:
5020
      return ParseWhileStatement(labels, own_labels, ok);
5021
    case Token::FOR:
5022
      if (V8_UNLIKELY(is_async_function() && PeekAhead() == Token::AWAIT)) {
5023
        return ParseForAwaitStatement(labels, own_labels, ok);
5024
      }
5025
      return ParseForStatement(labels, own_labels, ok);
5026
    case Token::CONTINUE:
5027
      return ParseContinueStatement(ok);
5028
    case Token::BREAK:
5029
      return ParseBreakStatement(labels, ok);
5030
    case Token::RETURN:
5031
      return ParseReturnStatement(ok);
5032
    case Token::THROW:
5033
      return ParseThrowStatement(ok);
5034
    case Token::TRY: {
5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045
      // It is somewhat complicated to have labels on try-statements.
      // When breaking out of a try-finally statement, one must take
      // great care not to treat it as a fall-through. It is much easier
      // just to wrap the entire try-statement in a statement block and
      // put the labels there.
      if (labels == nullptr) return ParseTryStatement(ok);
      BlockT result = factory()->NewBlock(1, false, labels);
      typename Types::Target target(this, result);
      StatementT statement = ParseTryStatement(CHECK_OK);
      result->statements()->Add(statement, zone());
      return result;
5046 5047
    }
    case Token::WITH:
5048
      return ParseWithStatement(labels, ok);
5049
    case Token::SWITCH:
5050
      return ParseSwitchStatement(labels, ok);
5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063
    case Token::FUNCTION:
      // FunctionDeclaration only allowed as a StatementListItem, not in
      // an arbitrary Statement position. Exceptions such as
      // ES#sec-functiondeclarations-in-ifstatement-statement-clauses
      // are handled by calling ParseScopedStatement rather than
      // ParseStatement directly.
      impl()->ReportMessageAt(scanner()->peek_location(),
                              is_strict(language_mode())
                                  ? MessageTemplate::kStrictFunction
                                  : MessageTemplate::kSloppyFunction);
      *ok = false;
      return impl()->NullStatement();
    case Token::DEBUGGER:
5064
      return ParseDebuggerStatement(ok);
5065
    case Token::VAR:
5066
      return ParseVariableStatement(kStatement, nullptr, ok);
5067
    case Token::ASYNC:
5068
      if (!scanner()->HasLineTerminatorAfterNext() &&
5069 5070 5071 5072 5073 5074 5075
          PeekAhead() == Token::FUNCTION) {
        impl()->ReportMessageAt(
            scanner()->peek_location(),
            MessageTemplate::kAsyncFunctionInSingleStatementContext);
        *ok = false;
        return impl()->NullStatement();
      }
5076
      V8_FALLTHROUGH;
5077
    default:
5078 5079
      return ParseExpressionOrLabelledStatement(labels, own_labels,
                                                allow_function, ok);
5080 5081 5082
  }
}

5083 5084
template <typename Impl>
typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseBlock(
5085
    ZonePtrList<const AstRawString>* labels, bool* ok) {
5086 5087 5088 5089
  // Block ::
  //   '{' StatementList '}'

  // Construct block expecting 16 statements.
5090
  BlockT body = factory()->NewBlock(16, false, labels);
5091 5092

  // Parse the statements and collect escaping labels.
5093
  Expect(Token::LBRACE, CHECK_OK_CUSTOM(NullStatement));
5094
  {
5095 5096
    BlockState block_state(zone(), &scope_);
    scope()->set_start_position(scanner()->location().beg_pos);
5097 5098 5099
    typename Types::Target target(this, body);

    while (peek() != Token::RBRACE) {
5100 5101
      StatementT stat = ParseStatementListItem(CHECK_OK_CUSTOM(NullStatement));
      if (!impl()->IsNull(stat) && !stat->IsEmptyStatement()) {
5102 5103 5104 5105
        body->statements()->Add(stat, zone());
      }
    }

5106
    Expect(Token::RBRACE, CHECK_OK_CUSTOM(NullStatement));
5107 5108 5109
    int end_pos = scanner()->location().end_pos;
    scope()->set_end_position(end_pos);
    impl()->RecordBlockSourceRange(body, end_pos);
5110
    body->set_scope(scope()->FinalizeBlockScope());
5111 5112 5113 5114
  }
  return body;
}

5115 5116
template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseScopedStatement(
5117
    ZonePtrList<const AstRawString>* labels, bool* ok) {
5118
  if (is_strict(language_mode()) || peek() != Token::FUNCTION) {
5119
    return ParseStatement(labels, nullptr, ok);
5120 5121 5122
  } else {
    // Make a block around the statement for a lexical binding
    // is introduced by a FunctionDeclaration.
5123 5124
    BlockState block_state(zone(), &scope_);
    scope()->set_start_position(scanner()->location().beg_pos);
5125
    BlockT block = factory()->NewBlock(1, false);
5126
    StatementT body = ParseFunctionDeclaration(CHECK_OK);
5127
    block->statements()->Add(body, zone());
5128 5129
    scope()->set_end_position(scanner()->location().end_pos);
    block->set_scope(scope()->FinalizeBlockScope());
5130 5131 5132 5133 5134 5135 5136
    return block;
  }
}

template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseVariableStatement(
    VariableDeclarationContext var_context,
5137
    ZonePtrList<const AstRawString>* names, bool* ok) {
5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174
  // VariableStatement ::
  //   VariableDeclarations ';'

  // The scope of a var declared variable anywhere inside a function
  // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
  // transform a source-level var declaration into a (Function) Scope
  // declaration, and rewrite the source-level initialization into an assignment
  // statement. We use a block to collect multiple assignments.
  //
  // We mark the block as initializer block because we don't want the
  // rewriter to add a '.result' assignment to such a block (to get compliant
  // behavior for code such as print(eval('var x = 7')), and for cosmetic
  // reasons when pretty-printing. Also, unless an assignment (initialization)
  // is inside an initializer block, it is ignored.

  DeclarationParsingResult parsing_result;
  StatementT result =
      ParseVariableDeclarations(var_context, &parsing_result, names, CHECK_OK);
  ExpectSemicolon(CHECK_OK);
  return result;
}

template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseDebuggerStatement(
    bool* ok) {
  // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
  // contexts this is used as a statement which invokes the debugger as i a
  // break point is present.
  // DebuggerStatement ::
  //   'debugger' ';'

  int pos = peek_position();
  Expect(Token::DEBUGGER, CHECK_OK);
  ExpectSemicolon(CHECK_OK);
  return factory()->NewDebuggerStatement(pos);
}

5175 5176 5177
template <typename Impl>
typename ParserBase<Impl>::StatementT
ParserBase<Impl>::ParseExpressionOrLabelledStatement(
5178
    ZonePtrList<const AstRawString>* labels,
5179
    ZonePtrList<const AstRawString>* own_labels,
5180 5181 5182 5183 5184 5185
    AllowLabelledFunctionStatement allow_function, bool* ok) {
  // ExpressionStatement | LabelledStatement ::
  //   Expression ';'
  //   Identifier ':' Statement
  //
  // ExpressionStatement[Yield] :
5186
  //   [lookahead notin {{, function, class, let [}] Expression[In, ?Yield] ;
5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197

  int pos = peek_position();

  switch (peek()) {
    case Token::FUNCTION:
    case Token::LBRACE:
      UNREACHABLE();  // Always handled by the callers.
    case Token::CLASS:
      ReportUnexpectedToken(Next());
      *ok = false;
      return impl()->NullStatement();
5198 5199 5200 5201
    case Token::LET: {
      Token::Value next_next = PeekAhead();
      // "let" followed by either "[", "{" or an identifier means a lexical
      // declaration, which should not appear here.
5202 5203 5204
      // However, ASI may insert a line break before an identifier or a brace.
      if (next_next != Token::LBRACK &&
          ((next_next != Token::LBRACE && next_next != Token::IDENTIFIER) ||
5205
           scanner_->HasLineTerminatorAfterNext())) {
5206 5207
        break;
      }
5208 5209 5210 5211
      impl()->ReportMessageAt(scanner()->peek_location(),
                              MessageTemplate::kUnexpectedLexicalDeclaration);
      *ok = false;
      return impl()->NullStatement();
5212
    }
5213 5214 5215 5216 5217 5218 5219 5220 5221 5222
    default:
      break;
  }

  bool starts_with_identifier = peek_any_identifier();
  ExpressionT expr = ParseExpression(true, CHECK_OK);
  if (peek() == Token::COLON && starts_with_identifier &&
      impl()->IsIdentifier(expr)) {
    // The whole expression was a single identifier, and not, e.g.,
    // something starting with an identifier or a parenthesized identifier.
5223 5224
    impl()->DeclareLabel(&labels, &own_labels,
                         impl()->AsIdentifierExpression(expr), CHECK_OK);
5225 5226
    Consume(Token::COLON);
    // ES#sec-labelled-function-declarations Labelled Function Declarations
5227 5228 5229
    if (peek() == Token::FUNCTION && is_sloppy(language_mode()) &&
        allow_function == kAllowLabelledFunctionStatement) {
      return ParseFunctionDeclaration(ok);
5230
    }
5231
    return ParseStatement(labels, own_labels, allow_function, ok);
5232 5233 5234 5235 5236 5237
  }

  // If we have an extension, we allow a native function declaration.
  // A native function declaration starts with "native function" with
  // no line-terminator between the two words.
  if (extension_ != nullptr && peek() == Token::FUNCTION &&
5238
      !scanner()->HasLineTerminatorBeforeNext() && impl()->IsNative(expr) &&
5239
      !scanner()->literal_contains_escapes()) {
5240
    return ParseNativeDeclaration(ok);
5241 5242 5243 5244 5245 5246 5247 5248 5249
  }

  // Parsed expression statement, followed by semicolon.
  ExpectSemicolon(CHECK_OK);
  return factory()->NewExpressionStatement(expr, pos);
}

template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseIfStatement(
5250
    ZonePtrList<const AstRawString>* labels, bool* ok) {
5251 5252 5253 5254 5255 5256 5257 5258
  // IfStatement ::
  //   'if' '(' Expression ')' Statement ('else' Statement)?

  int pos = peek_position();
  Expect(Token::IF, CHECK_OK);
  Expect(Token::LPAREN, CHECK_OK);
  ExpressionT condition = ParseExpression(true, CHECK_OK);
  Expect(Token::RPAREN, CHECK_OK);
5259 5260 5261 5262 5263 5264 5265 5266

  SourceRange then_range, else_range;
  StatementT then_statement = impl()->NullStatement();
  {
    SourceRangeScope range_scope(scanner(), &then_range);
    then_statement = ParseScopedStatement(labels, CHECK_OK);
  }

5267 5268
  StatementT else_statement = impl()->NullStatement();
  if (Check(Token::ELSE)) {
5269
    else_range = SourceRange::ContinuationOf(then_range);
5270
    else_statement = ParseScopedStatement(labels, CHECK_OK);
5271
    else_range.end = scanner_->location().end_pos;
5272 5273 5274
  } else {
    else_statement = factory()->NewEmptyStatement(kNoSourcePosition);
  }
5275 5276 5277 5278
  StatementT stmt =
      factory()->NewIfStatement(condition, then_statement, else_statement, pos);
  impl()->RecordIfStatementSourceRange(stmt, then_range, else_range);
  return stmt;
5279 5280 5281 5282 5283 5284 5285 5286 5287 5288
}

template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseContinueStatement(
    bool* ok) {
  // ContinueStatement ::
  //   'continue' Identifier? ';'

  int pos = peek_position();
  Expect(Token::CONTINUE, CHECK_OK);
5289
  IdentifierT label = impl()->NullIdentifier();
5290
  Token::Value tok = peek();
5291
  if (!scanner()->HasLineTerminatorBeforeNext() && tok != Token::SEMICOLON &&
5292 5293 5294 5295
      tok != Token::RBRACE && tok != Token::EOS) {
    // ECMA allows "eval" or "arguments" as labels even in strict mode.
    label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
  }
5296
  typename Types::IterationStatement target =
5297
      impl()->LookupContinueTarget(label, CHECK_OK);
5298
  if (impl()->IsNull(target)) {
5299 5300
    // Illegal continue statement.
    MessageTemplate::Template message = MessageTemplate::kIllegalContinue;
5301 5302
    typename Types::BreakableStatement breakable_target =
        impl()->LookupBreakTarget(label, CHECK_OK);
5303
    if (impl()->IsNull(label)) {
5304
      message = MessageTemplate::kNoIterationStatement;
5305
    } else if (impl()->IsNull(breakable_target)) {
5306 5307 5308 5309 5310 5311 5312
      message = MessageTemplate::kUnknownLabel;
    }
    ReportMessage(message, label);
    *ok = false;
    return impl()->NullStatement();
  }
  ExpectSemicolon(CHECK_OK);
5313 5314 5315
  StatementT stmt = factory()->NewContinueStatement(target, pos);
  impl()->RecordJumpStatementSourceRange(stmt, scanner_->location().end_pos);
  return stmt;
5316 5317 5318 5319
}

template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseBreakStatement(
5320
    ZonePtrList<const AstRawString>* labels, bool* ok) {
5321 5322 5323 5324 5325
  // BreakStatement ::
  //   'break' Identifier? ';'

  int pos = peek_position();
  Expect(Token::BREAK, CHECK_OK);
5326
  IdentifierT label = impl()->NullIdentifier();
5327
  Token::Value tok = peek();
5328
  if (!scanner()->HasLineTerminatorBeforeNext() && tok != Token::SEMICOLON &&
5329 5330 5331 5332 5333 5334
      tok != Token::RBRACE && tok != Token::EOS) {
    // ECMA allows "eval" or "arguments" as labels even in strict mode.
    label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
  }
  // Parse labeled break statements that target themselves into
  // empty statements, e.g. 'l1: l2: l3: break l2;'
5335
  if (!impl()->IsNull(label) && impl()->ContainsLabel(labels, label)) {
5336 5337 5338
    ExpectSemicolon(CHECK_OK);
    return factory()->NewEmptyStatement(pos);
  }
5339
  typename Types::BreakableStatement target =
5340
      impl()->LookupBreakTarget(label, CHECK_OK);
5341
  if (impl()->IsNull(target)) {
5342 5343
    // Illegal break statement.
    MessageTemplate::Template message = MessageTemplate::kIllegalBreak;
5344
    if (!impl()->IsNull(label)) {
5345 5346 5347 5348 5349 5350 5351
      message = MessageTemplate::kUnknownLabel;
    }
    ReportMessage(message, label);
    *ok = false;
    return impl()->NullStatement();
  }
  ExpectSemicolon(CHECK_OK);
5352 5353 5354
  StatementT stmt = factory()->NewBreakStatement(target, pos);
  impl()->RecordJumpStatementSourceRange(stmt, scanner_->location().end_pos);
  return stmt;
5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368
}

template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseReturnStatement(
    bool* ok) {
  // ReturnStatement ::
  //   'return' [no line terminator] Expression? ';'

  // Consume the return token. It is necessary to do that before
  // reporting any errors on it, because of the way errors are
  // reported (underlining).
  Expect(Token::RETURN, CHECK_OK);
  Scanner::Location loc = scanner()->location();

5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379
  switch (GetDeclarationScope()->scope_type()) {
    case SCRIPT_SCOPE:
    case EVAL_SCOPE:
    case MODULE_SCOPE:
      impl()->ReportMessageAt(loc, MessageTemplate::kIllegalReturn);
      *ok = false;
      return impl()->NullStatement();
    default:
      break;
  }

5380
  Token::Value tok = peek();
5381
  ExpressionT return_value = impl()->NullExpression();
5382
  if (scanner()->HasLineTerminatorBeforeNext() || tok == Token::SEMICOLON ||
5383
      tok == Token::RBRACE || tok == Token::EOS) {
5384
    if (IsDerivedConstructor(function_state_->kind())) {
5385 5386 5387
      return_value = impl()->ThisExpression(loc.beg_pos);
    }
  } else {
5388
    return_value = ParseExpression(true, CHECK_OK);
5389 5390 5391
  }
  ExpectSemicolon(CHECK_OK);
  return_value = impl()->RewriteReturn(return_value, loc.beg_pos);
5392 5393 5394
  int continuation_pos = scanner_->location().end_pos;
  StatementT stmt =
      BuildReturnStatement(return_value, loc.beg_pos, continuation_pos);
5395 5396
  impl()->RecordJumpStatementSourceRange(stmt, scanner_->location().end_pos);
  return stmt;
5397 5398 5399 5400
}

template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseWithStatement(
5401
    ZonePtrList<const AstRawString>* labels, bool* ok) {
5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420
  // WithStatement ::
  //   'with' '(' Expression ')' Statement

  Expect(Token::WITH, CHECK_OK);
  int pos = position();

  if (is_strict(language_mode())) {
    ReportMessage(MessageTemplate::kStrictWith);
    *ok = false;
    return impl()->NullStatement();
  }

  Expect(Token::LPAREN, CHECK_OK);
  ExpressionT expr = ParseExpression(true, CHECK_OK);
  Expect(Token::RPAREN, CHECK_OK);

  Scope* with_scope = NewScope(WITH_SCOPE);
  StatementT body = impl()->NullStatement();
  {
5421
    BlockState block_state(&scope_, with_scope);
5422
    with_scope->set_start_position(scanner()->peek_location().beg_pos);
5423
    body = ParseStatement(labels, nullptr, CHECK_OK);
5424 5425 5426 5427 5428
    with_scope->set_end_position(scanner()->location().end_pos);
  }
  return factory()->NewWithStatement(with_scope, expr, body, pos);
}

5429 5430
template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseDoWhileStatement(
5431 5432
    ZonePtrList<const AstRawString>* labels,
    ZonePtrList<const AstRawString>* own_labels, bool* ok) {
5433 5434 5435
  // DoStatement ::
  //   'do' Statement 'while' '(' Expression ')' ';'

5436 5437
  auto loop =
      factory()->NewDoWhileStatement(labels, own_labels, peek_position());
5438 5439
  typename Types::Target target(this, loop);

5440 5441 5442
  SourceRange body_range;
  StatementT body = impl()->NullStatement();

5443
  Expect(Token::DO, CHECK_OK);
5444 5445
  {
    SourceRangeScope range_scope(scanner(), &body_range);
5446
    body = ParseStatement(nullptr, nullptr, CHECK_OK);
5447
  }
5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 5459
  Expect(Token::WHILE, CHECK_OK);
  Expect(Token::LPAREN, CHECK_OK);

  ExpressionT cond = ParseExpression(true, CHECK_OK);
  Expect(Token::RPAREN, CHECK_OK);

  // Allow do-statements to be terminated with and without
  // semi-colons. This allows code such as 'do;while(0)return' to
  // parse, which would not be the case if we had used the
  // ExpectSemicolon() functionality here.
  Check(Token::SEMICOLON);

5460 5461 5462
  loop->Initialize(cond, body);
  impl()->RecordIterationStatementSourceRange(loop, body_range);

5463 5464 5465 5466 5467
  return loop;
}

template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseWhileStatement(
5468 5469
    ZonePtrList<const AstRawString>* labels,
    ZonePtrList<const AstRawString>* own_labels, bool* ok) {
5470 5471 5472
  // WhileStatement ::
  //   'while' '(' Expression ')' Statement

5473
  auto loop = factory()->NewWhileStatement(labels, own_labels, peek_position());
5474 5475
  typename Types::Target target(this, loop);

5476 5477 5478
  SourceRange body_range;
  StatementT body = impl()->NullStatement();

5479 5480 5481 5482
  Expect(Token::WHILE, CHECK_OK);
  Expect(Token::LPAREN, CHECK_OK);
  ExpressionT cond = ParseExpression(true, CHECK_OK);
  Expect(Token::RPAREN, CHECK_OK);
5483 5484
  {
    SourceRangeScope range_scope(scanner(), &body_range);
5485
    body = ParseStatement(nullptr, nullptr, CHECK_OK);
5486
  }
5487

5488 5489 5490
  loop->Initialize(cond, body);
  impl()->RecordIterationStatementSourceRange(loop, body_range);

5491 5492 5493 5494 5495 5496 5497 5498 5499 5500 5501
  return loop;
}

template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseThrowStatement(
    bool* ok) {
  // ThrowStatement ::
  //   'throw' Expression ';'

  Expect(Token::THROW, CHECK_OK);
  int pos = position();
5502
  if (scanner()->HasLineTerminatorBeforeNext()) {
5503 5504 5505 5506 5507 5508 5509
    ReportMessage(MessageTemplate::kNewlineAfterThrow);
    *ok = false;
    return impl()->NullStatement();
  }
  ExpressionT exception = ParseExpression(true, CHECK_OK);
  ExpectSemicolon(CHECK_OK);

5510 5511 5512 5513
  StatementT stmt = impl()->NewThrowStatement(exception, pos);
  impl()->RecordThrowSourceRange(stmt, scanner_->location().end_pos);

  return stmt;
5514 5515
}

5516 5517
template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseSwitchStatement(
5518
    ZonePtrList<const AstRawString>* labels, bool* ok) {
5519 5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531
  // SwitchStatement ::
  //   'switch' '(' Expression ')' '{' CaseClause* '}'
  // CaseClause ::
  //   'case' Expression ':' StatementList
  //   'default' ':' StatementList

  int switch_pos = peek_position();

  Expect(Token::SWITCH, CHECK_OK);
  Expect(Token::LPAREN, CHECK_OK);
  ExpressionT tag = ParseExpression(true, CHECK_OK);
  Expect(Token::RPAREN, CHECK_OK);

5532 5533
  auto switch_statement =
      factory()->NewSwitchStatement(labels, tag, switch_pos);
5534 5535

  {
5536
    BlockState cases_block_state(zone(), &scope_);
5537
    scope()->set_start_position(switch_pos);
5538
    scope()->SetNonlinear();
5539 5540 5541 5542 5543 5544
    typename Types::Target target(this, switch_statement);

    bool default_seen = false;
    Expect(Token::LBRACE, CHECK_OK);
    while (peek() != Token::RBRACE) {
      // An empty label indicates the default case.
5545
      ExpressionT label = impl()->NullExpression();
5546 5547
      SourceRange clause_range;
      SourceRangeScope range_scope(scanner(), &clause_range);
5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 5565
      if (Check(Token::CASE)) {
        label = ParseExpression(true, CHECK_OK);
      } else {
        Expect(Token::DEFAULT, CHECK_OK);
        if (default_seen) {
          ReportMessage(MessageTemplate::kMultipleDefaultsInSwitch);
          *ok = false;
          return impl()->NullStatement();
        }
        default_seen = true;
      }
      Expect(Token::COLON, CHECK_OK);
      StatementListT statements = impl()->NewStatementList(5);
      while (peek() != Token::CASE && peek() != Token::DEFAULT &&
             peek() != Token::RBRACE) {
        StatementT stat = ParseStatementListItem(CHECK_OK);
        statements->Add(stat, zone());
      }
5566
      auto clause = factory()->NewCaseClause(label, statements);
5567
      impl()->RecordCaseClauseSourceRange(clause, range_scope.Finalize());
5568
      switch_statement->cases()->Add(clause, zone());
5569 5570 5571
    }
    Expect(Token::RBRACE, CHECK_OK);

5572 5573
    int end_position = scanner()->location().end_pos;
    scope()->set_end_position(end_position);
5574
    impl()->RecordSwitchStatementSourceRange(switch_statement, end_position);
5575 5576 5577 5578 5579
    Scope* switch_scope = scope()->FinalizeBlockScope();
    if (switch_scope != nullptr) {
      return impl()->RewriteSwitchStatement(switch_statement, switch_scope);
    }
    return switch_statement;
5580 5581 5582
  }
}

5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599
template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseTryStatement(
    bool* ok) {
  // TryStatement ::
  //   'try' Block Catch
  //   'try' Block Finally
  //   'try' Block Catch Finally
  //
  // Catch ::
  //   'catch' '(' Identifier ')' Block
  //
  // Finally ::
  //   'finally' Block

  Expect(Token::TRY, CHECK_OK);
  int pos = position();

5600
  BlockT try_block = ParseBlock(nullptr, CHECK_OK);
5601 5602 5603 5604 5605 5606 5607 5608 5609

  CatchInfo catch_info(this);

  if (peek() != Token::CATCH && peek() != Token::FINALLY) {
    ReportMessage(MessageTemplate::kNoCatchOrFinally);
    *ok = false;
    return impl()->NullStatement();
  }

5610 5611
  SourceRange catch_range, finally_range;

5612
  BlockT catch_block = impl()->NullStatement();
5613 5614 5615
  {
    SourceRangeScope catch_range_scope(scanner(), &catch_range);
    if (Check(Token::CATCH)) {
5616
      bool has_binding;
5617
      has_binding = Check(Token::LPAREN);
5618

5619 5620 5621
      if (has_binding) {
        catch_info.scope = NewScope(CATCH_SCOPE);
        catch_info.scope->set_start_position(scanner()->location().beg_pos);
5622

5623
        {
5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645
          BlockState catch_block_state(&scope_, catch_info.scope);

          catch_block = factory()->NewBlock(16, false);

          // Create a block scope to hold any lexical declarations created
          // as part of destructuring the catch parameter.
          {
            BlockState catch_variable_block_state(zone(), &scope_);
            scope()->set_start_position(scanner()->location().beg_pos);

            // This does not simply call ParsePrimaryExpression to avoid
            // ExpressionFromIdentifier from being called in the first
            // branch, which would introduce an unresolved symbol and mess
            // with arrow function names.
            if (peek_any_identifier()) {
              catch_info.name =
                  ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK);
            } else {
              ExpressionClassifier pattern_classifier(this);
              catch_info.pattern = ParsePrimaryExpression(CHECK_OK);
              ValidateBindingPattern(CHECK_OK);
            }
5646

5647 5648 5649 5650 5651
            Expect(Token::RPAREN, CHECK_OK);
            impl()->RewriteCatchPattern(&catch_info, CHECK_OK);
            if (!impl()->IsNull(catch_info.init_block)) {
              catch_block->statements()->Add(catch_info.init_block, zone());
            }
5652

5653 5654 5655 5656 5657 5658
            catch_info.inner_block = ParseBlock(nullptr, CHECK_OK);
            catch_block->statements()->Add(catch_info.inner_block, zone());
            impl()->ValidateCatchBlock(catch_info, CHECK_OK);
            scope()->set_end_position(scanner()->location().end_pos);
            catch_block->set_scope(scope()->FinalizeBlockScope());
          }
5659 5660
        }

5661 5662 5663 5664
        catch_info.scope->set_end_position(scanner()->location().end_pos);
      } else {
        catch_block = ParseBlock(nullptr, CHECK_OK);
      }
5665
    }
5666 5667
  }

5668 5669
  BlockT finally_block = impl()->NullStatement();
  DCHECK(peek() == Token::FINALLY || !impl()->IsNull(catch_block));
5670
  {
5671
    SourceRangeScope range_scope(scanner(), &finally_range);
5672 5673 5674
    if (Check(Token::FINALLY)) {
      finally_block = ParseBlock(nullptr, CHECK_OK);
    }
5675 5676
  }

5677 5678 5679
  return impl()->RewriteTryStatement(try_block, catch_block, catch_range,
                                     finally_block, finally_range, catch_info,
                                     pos);
5680 5681
}

5682 5683
template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForStatement(
5684 5685
    ZonePtrList<const AstRawString>* labels,
    ZonePtrList<const AstRawString>* own_labels, bool* ok) {
5686 5687 5688 5689 5690 5691 5692 5693
  // Either a standard for loop
  //   for (<init>; <cond>; <next>) { ... }
  // or a for-each loop
  //   for (<each> of|in <iterable>) { ... }
  //
  // We parse a declaration/expression after the 'for (' and then read the first
  // expression/declaration before we know if this is a for or a for-each.

5694 5695 5696 5697 5698 5699
  int stmt_pos = peek_position();
  ForInfo for_info(this);

  Expect(Token::FOR, CHECK_OK);
  Expect(Token::LPAREN, CHECK_OK);

5700 5701 5702
  if (peek() == Token::CONST || (peek() == Token::LET && IsNextLetKeyword())) {
    // The initializer contains lexical declarations,
    // so create an in-between scope.
5703 5704
    BlockState for_state(zone(), &scope_);
    scope()->set_start_position(scanner()->location().beg_pos);
5705

5706 5707 5708 5709 5710 5711
    // Also record whether inner functions or evals are found inside
    // this loop, as this information is used to simplify the desugaring
    // if none are found.
    typename FunctionState::FunctionOrEvalRecordingScope recording_scope(
        function_state_);

5712 5713 5714 5715 5716 5717 5718 5719
    // Create an inner block scope which will be the parent scope of scopes
    // possibly created by ParseVariableDeclarations.
    Scope* inner_block_scope = NewScope(BLOCK_SCOPE);
    {
      BlockState inner_state(&scope_, inner_block_scope);
      ParseVariableDeclarations(kForStatement, &for_info.parsing_result,
                                nullptr, CHECK_OK);
    }
5720
    DCHECK(IsLexicalVariableMode(for_info.parsing_result.descriptor.mode));
5721 5722 5723
    for_info.position = scanner()->location().beg_pos;

    if (CheckInOrOf(&for_info.mode)) {
5724
      scope()->set_is_hidden();
5725 5726
      return ParseForEachStatementWithDeclarations(
          stmt_pos, &for_info, labels, own_labels, inner_block_scope, ok);
5727 5728
    }

5729 5730 5731
    Expect(Token::SEMICOLON, CHECK_OK);

    StatementT init = impl()->BuildInitializationBlock(
5732
        &for_info.parsing_result, &for_info.bound_names, CHECK_OK);
5733 5734 5735 5736 5737

    Scope* finalized = inner_block_scope->FinalizeBlockScope();
    // No variable declarations will have been created in inner_block_scope.
    DCHECK_NULL(finalized);
    USE(finalized);
5738 5739
    return ParseStandardForLoopWithLexicalDeclarations(
        stmt_pos, init, &for_info, labels, own_labels, ok);
5740 5741 5742
  }

  StatementT init = impl()->NullStatement();
5743 5744 5745
  if (peek() == Token::VAR) {
    ParseVariableDeclarations(kForStatement, &for_info.parsing_result, nullptr,
                              CHECK_OK);
5746
    DCHECK_EQ(for_info.parsing_result.descriptor.mode, VariableMode::kVar);
5747 5748 5749 5750
    for_info.position = scanner()->location().beg_pos;

    if (CheckInOrOf(&for_info.mode)) {
      return ParseForEachStatementWithDeclarations(stmt_pos, &for_info, labels,
5751
                                                   own_labels, nullptr, ok);
5752 5753 5754 5755 5756
    }

    init = impl()->BuildInitializationBlock(&for_info.parsing_result, nullptr,
                                            CHECK_OK);
  } else if (peek() != Token::SEMICOLON) {
5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769
    // The initializer does not contain declarations.
    int lhs_beg_pos = peek_position();
    ExpressionClassifier classifier(this);
    ExpressionT expression = ParseExpressionCoverGrammar(false, CHECK_OK);
    int lhs_end_pos = scanner()->location().end_pos;

    bool is_for_each = CheckInOrOf(&for_info.mode);
    bool is_destructuring = is_for_each && (expression->IsArrayLiteral() ||
                                            expression->IsObjectLiteral());

    if (is_destructuring) {
      ValidateAssignmentPattern(CHECK_OK);
    } else {
5770
      ValidateExpression(CHECK_OK);
5771
    }
5772

5773
    if (is_for_each) {
5774 5775 5776
      return ParseForEachStatementWithoutDeclarations(
          stmt_pos, expression, lhs_beg_pos, lhs_end_pos, &for_info, labels,
          own_labels, ok);
5777 5778 5779 5780
    }
    // Initializer is just an expression.
    init = factory()->NewExpressionStatement(expression, lhs_beg_pos);
  }
5781

5782 5783
  Expect(Token::SEMICOLON, CHECK_OK);

5784
  // Standard 'for' loop, we have parsed the initializer at this point.
5785
  ExpressionT cond = impl()->NullExpression();
5786 5787
  StatementT next = impl()->NullStatement();
  StatementT body = impl()->NullStatement();
5788 5789
  ForStatementT loop = ParseStandardForLoop(stmt_pos, labels, own_labels, &cond,
                                            &next, &body, CHECK_OK);
5790 5791
  loop->Initialize(init, cond, next, body);
  return loop;
5792
}
5793

5794 5795 5796
template <typename Impl>
typename ParserBase<Impl>::StatementT
ParserBase<Impl>::ParseForEachStatementWithDeclarations(
5797
    int stmt_pos, ForInfo* for_info, ZonePtrList<const AstRawString>* labels,
5798 5799
    ZonePtrList<const AstRawString>* own_labels, Scope* inner_block_scope,
    bool* ok) {
5800
  // Just one declaration followed by in/of.
5801
  if (for_info->parsing_result.declarations.size() != 1) {
5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819
    impl()->ReportMessageAt(for_info->parsing_result.bindings_loc,
                            MessageTemplate::kForInOfLoopMultiBindings,
                            ForEachStatement::VisitModeString(for_info->mode));
    *ok = false;
    return impl()->NullStatement();
  }
  if (for_info->parsing_result.first_initializer_loc.IsValid() &&
      (is_strict(language_mode()) ||
       for_info->mode == ForEachStatement::ITERATE ||
       IsLexicalVariableMode(for_info->parsing_result.descriptor.mode) ||
       !impl()->IsIdentifier(
           for_info->parsing_result.declarations[0].pattern))) {
    impl()->ReportMessageAt(for_info->parsing_result.first_initializer_loc,
                            MessageTemplate::kForInOfLoopInitializer,
                            ForEachStatement::VisitModeString(for_info->mode));
    *ok = false;
    return impl()->NullStatement();
  }
5820

5821 5822 5823 5824
  // Reset the declaration_kind to ensure proper processing during declaration.
  for_info->parsing_result.descriptor.declaration_kind =
      DeclarationDescriptor::FOR_EACH;

5825
  BlockT init_block = impl()->RewriteForVarInLegacy(*for_info);
5826

5827 5828
  auto loop = factory()->NewForEachStatement(for_info->mode, labels, own_labels,
                                             stmt_pos);
5829
  typename Types::Target target(this, loop);
5830

5831
  ExpressionT enumerable = impl()->NullExpression();
5832 5833 5834
  if (for_info->mode == ForEachStatement::ITERATE) {
    ExpressionClassifier classifier(this);
    enumerable = ParseAssignmentExpression(true, CHECK_OK);
5835
    ValidateExpression(CHECK_OK);
5836 5837 5838
  } else {
    enumerable = ParseExpression(true, CHECK_OK);
  }
5839

5840
  Expect(Token::RPAREN, CHECK_OK);
5841

5842 5843 5844
  Scope* for_scope = nullptr;
  if (inner_block_scope != nullptr) {
    for_scope = inner_block_scope->outer_scope();
5845
    DCHECK_EQ(for_scope, scope());
5846 5847 5848
    inner_block_scope->set_start_position(scanner()->location().beg_pos);
  }

5849 5850
  ExpressionT each_variable = impl()->NullExpression();
  BlockT body_block = impl()->NullStatement();
5851
  {
5852 5853
    BlockState block_state(
        &scope_, inner_block_scope != nullptr ? inner_block_scope : scope_);
5854

5855 5856 5857
    SourceRange body_range;
    SourceRangeScope range_scope(scanner(), &body_range);

5858
    StatementT body = ParseStatement(nullptr, nullptr, CHECK_OK);
5859
    impl()->RecordIterationStatementSourceRange(loop, range_scope.Finalize());
5860

5861 5862 5863
    impl()->DesugarBindingInForEachStatement(for_info, &body_block,
                                             &each_variable, CHECK_OK);
    body_block->statements()->Add(body, zone());
5864

5865 5866 5867 5868
    if (inner_block_scope != nullptr) {
      inner_block_scope->set_end_position(scanner()->location().end_pos);
      body_block->set_scope(inner_block_scope->FinalizeBlockScope());
    }
5869
  }
5870

5871 5872 5873
  StatementT final_loop = impl()->InitializeForEachStatement(
      loop, each_variable, enumerable, body_block);

5874
  init_block = impl()->CreateForEachStatementTDZ(init_block, *for_info, ok);
5875

5876 5877 5878 5879 5880
  if (for_scope != nullptr) {
    for_scope->set_end_position(scanner()->location().end_pos);
    for_scope = for_scope->FinalizeBlockScope();
  }

5881
  // Parsed for-in loop w/ variable declarations.
5882
  if (!impl()->IsNull(init_block)) {
5883 5884 5885 5886
    init_block->statements()->Add(final_loop, zone());
    init_block->set_scope(for_scope);
    return init_block;
  }
5887

5888 5889 5890 5891 5892 5893 5894 5895
  DCHECK_NULL(for_scope);
  return final_loop;
}

template <typename Impl>
typename ParserBase<Impl>::StatementT
ParserBase<Impl>::ParseForEachStatementWithoutDeclarations(
    int stmt_pos, ExpressionT expression, int lhs_beg_pos, int lhs_end_pos,
5896 5897
    ForInfo* for_info, ZonePtrList<const AstRawString>* labels,
    ZonePtrList<const AstRawString>* own_labels, bool* ok) {
5898 5899
  // Initializer is reference followed by in/of.
  if (!expression->IsArrayLiteral() && !expression->IsObjectLiteral()) {
5900
    expression = CheckAndRewriteReferenceExpression(
5901 5902
        expression, lhs_beg_pos, lhs_end_pos, MessageTemplate::kInvalidLhsInFor,
        kSyntaxError, CHECK_OK);
5903 5904
  }

5905 5906
  auto loop = factory()->NewForEachStatement(for_info->mode, labels, own_labels,
                                             stmt_pos);
5907 5908
  typename Types::Target target(this, loop);

5909
  ExpressionT enumerable = impl()->NullExpression();
5910 5911 5912
  if (for_info->mode == ForEachStatement::ITERATE) {
    ExpressionClassifier classifier(this);
    enumerable = ParseAssignmentExpression(true, CHECK_OK);
5913
    ValidateExpression(CHECK_OK);
5914 5915 5916 5917 5918 5919
  } else {
    enumerable = ParseExpression(true, CHECK_OK);
  }

  Expect(Token::RPAREN, CHECK_OK);

5920
  StatementT body = impl()->NullStatement();
5921
  {
5922 5923 5924
    SourceRange body_range;
    SourceRangeScope range_scope(scanner(), &body_range);

5925
    body = ParseStatement(nullptr, nullptr, CHECK_OK);
5926
    impl()->RecordIterationStatementSourceRange(loop, range_scope.Finalize());
5927
  }
5928
  return impl()->InitializeForEachStatement(loop, expression, enumerable, body);
5929 5930 5931
}

template <typename Impl>
5932
typename ParserBase<Impl>::StatementT
5933 5934
ParserBase<Impl>::ParseStandardForLoopWithLexicalDeclarations(
    int stmt_pos, StatementT init, ForInfo* for_info,
5935 5936
    ZonePtrList<const AstRawString>* labels,
    ZonePtrList<const AstRawString>* own_labels, bool* ok) {
5937 5938 5939
  // The condition and the next statement of the for loop must be parsed
  // in a new scope.
  Scope* inner_scope = NewScope(BLOCK_SCOPE);
5940
  ForStatementT loop = impl()->NullStatement();
5941
  ExpressionT cond = impl()->NullExpression();
5942 5943
  StatementT next = impl()->NullStatement();
  StatementT body = impl()->NullStatement();
5944
  {
5945
    BlockState block_state(&scope_, inner_scope);
5946
    scope()->set_start_position(scanner()->location().beg_pos);
5947 5948
    loop = ParseStandardForLoop(stmt_pos, labels, own_labels, &cond, &next,
                                &body, CHECK_OK);
5949
    scope()->set_end_position(scanner()->location().end_pos);
5950 5951
  }

5952
  scope()->set_end_position(scanner()->location().end_pos);
5953 5954 5955 5956 5957 5958 5959 5960 5961
  if (for_info->bound_names.length() > 0 &&
      function_state_->contains_function_or_eval()) {
    scope()->set_is_hidden();
    return impl()->DesugarLexicalBindingsInForStatement(
        loop, init, cond, next, body, inner_scope, *for_info, ok);
  } else {
    inner_scope = inner_scope->FinalizeBlockScope();
    DCHECK_NULL(inner_scope);
    USE(inner_scope);
5962
  }
5963

5964
  Scope* for_scope = scope()->FinalizeBlockScope();
5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975
  if (for_scope != nullptr) {
    // Rewrite a for statement of the form
    //   for (const x = i; c; n) b
    //
    // into
    //
    //   {
    //     const x = i;
    //     for (; c; n) b
    //   }
    //
5976
    DCHECK(!impl()->IsNull(init));
5977
    BlockT block = factory()->NewBlock(2, false);
5978
    block->statements()->Add(init, zone());
5979 5980
    block->statements()->Add(loop, zone());
    block->set_scope(for_scope);
5981
    loop->Initialize(impl()->NullStatement(), cond, next, body);
5982 5983 5984
    return block;
  }

5985
  loop->Initialize(init, cond, next, body);
5986 5987 5988 5989 5990
  return loop;
}

template <typename Impl>
typename ParserBase<Impl>::ForStatementT ParserBase<Impl>::ParseStandardForLoop(
5991 5992
    int stmt_pos, ZonePtrList<const AstRawString>* labels,
    ZonePtrList<const AstRawString>* own_labels, ExpressionT* cond,
5993
    StatementT* next, StatementT* body, bool* ok) {
5994
  ForStatementT loop = factory()->NewForStatement(labels, own_labels, stmt_pos);
5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010
  typename Types::Target target(this, loop);

  if (peek() != Token::SEMICOLON) {
    *cond = ParseExpression(true, CHECK_OK);
  }
  Expect(Token::SEMICOLON, CHECK_OK);

  if (peek() != Token::RPAREN) {
    ExpressionT exp = ParseExpression(true, CHECK_OK);
    *next = factory()->NewExpressionStatement(exp, exp->position());
  }
  Expect(Token::RPAREN, CHECK_OK);

  SourceRange body_range;
  {
    SourceRangeScope range_scope(scanner(), &body_range);
6011
    *body = ParseStatement(nullptr, nullptr, CHECK_OK);
6012
  }
6013
  impl()->RecordIterationStatementSourceRange(loop, body_range);
6014

6015
  return loop;
6016 6017
}

6018
template <typename Impl>
6019 6020 6021 6022 6023 6024
void ParserBase<Impl>::MarkLoopVariableAsAssigned(
    Scope* scope, Variable* var,
    typename DeclarationDescriptor::Kind declaration_kind) {
  if (!IsLexicalVariableMode(var->mode()) &&
      (!scope->is_function_scope() ||
       declaration_kind == DeclarationDescriptor::FOR_EACH)) {
6025 6026 6027
    var->set_maybe_assigned();
  }
}
6028

6029 6030
template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForAwaitStatement(
6031 6032
    ZonePtrList<const AstRawString>* labels,
    ZonePtrList<const AstRawString>* own_labels, bool* ok) {
6033 6034 6035 6036 6037 6038 6039 6040 6041
  // for await '(' ForDeclaration of AssignmentExpression ')'
  DCHECK(is_async_function());

  int stmt_pos = peek_position();

  ForInfo for_info(this);
  for_info.mode = ForEachStatement::ITERATE;

  // Create an in-between scope for let-bound iteration variables.
6042
  BlockState for_state(zone(), &scope_);
6043 6044 6045
  Expect(Token::FOR, CHECK_OK);
  Expect(Token::AWAIT, CHECK_OK);
  Expect(Token::LPAREN, CHECK_OK);
6046 6047
  scope()->set_start_position(scanner()->location().beg_pos);
  scope()->set_is_hidden();
6048

6049
  auto loop = factory()->NewForOfStatement(labels, own_labels, stmt_pos);
6050 6051
  typename Types::Target target(this, loop);

6052
  ExpressionT each_variable = impl()->NullExpression();
6053 6054

  bool has_declarations = false;
6055
  Scope* inner_block_scope = NewScope(BLOCK_SCOPE);
6056 6057 6058 6059 6060 6061 6062 6063 6064

  if (peek() == Token::VAR || peek() == Token::CONST ||
      (peek() == Token::LET && IsNextLetKeyword())) {
    // The initializer contains declarations
    // 'for' 'await' '(' ForDeclaration 'of' AssignmentExpression ')'
    //     Statement
    // 'for' 'await' '(' 'var' ForBinding 'of' AssignmentExpression ')'
    //     Statement
    has_declarations = true;
6065 6066 6067 6068 6069 6070

    {
      BlockState inner_state(&scope_, inner_block_scope);
      ParseVariableDeclarations(kForStatement, &for_info.parsing_result,
                                nullptr, CHECK_OK);
    }
6071 6072 6073
    for_info.position = scanner()->location().beg_pos;

    // Only a single declaration is allowed in for-await-of loops
6074
    if (for_info.parsing_result.declarations.size() != 1) {
6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094
      impl()->ReportMessageAt(for_info.parsing_result.bindings_loc,
                              MessageTemplate::kForInOfLoopMultiBindings,
                              "for-await-of");
      *ok = false;
      return impl()->NullStatement();
    }

    // for-await-of's declarations do not permit initializers.
    if (for_info.parsing_result.first_initializer_loc.IsValid()) {
      impl()->ReportMessageAt(for_info.parsing_result.first_initializer_loc,
                              MessageTemplate::kForInOfLoopInitializer,
                              "for-await-of");
      *ok = false;
      return impl()->NullStatement();
    }
  } else {
    // The initializer does not contain declarations.
    // 'for' 'await' '(' LeftHandSideExpression 'of' AssignmentExpression ')'
    //     Statement
    int lhs_beg_pos = peek_position();
6095
    BlockState inner_state(&scope_, inner_block_scope);
6096 6097 6098 6099 6100 6101 6102
    ExpressionClassifier classifier(this);
    ExpressionT lhs = each_variable = ParseLeftHandSideExpression(CHECK_OK);
    int lhs_end_pos = scanner()->location().end_pos;

    if (lhs->IsArrayLiteral() || lhs->IsObjectLiteral()) {
      ValidateAssignmentPattern(CHECK_OK);
    } else {
6103
      ValidateExpression(CHECK_OK);
6104
      each_variable = CheckAndRewriteReferenceExpression(
6105 6106 6107 6108 6109
          lhs, lhs_beg_pos, lhs_end_pos, MessageTemplate::kInvalidLhsInFor,
          kSyntaxError, CHECK_OK);
    }
  }

6110
  ExpectContextualKeyword(Token::OF, CHECK_OK);
6111 6112 6113
  int each_keyword_pos = scanner()->location().beg_pos;

  const bool kAllowIn = true;
6114
  ExpressionT iterable = impl()->NullExpression();
6115 6116 6117 6118

  {
    ExpressionClassifier classifier(this);
    iterable = ParseAssignmentExpression(kAllowIn, CHECK_OK);
6119
    ValidateExpression(CHECK_OK);
6120 6121 6122 6123
  }

  Expect(Token::RPAREN, CHECK_OK);

6124
  StatementT body = impl()->NullStatement();
6125
  {
6126
    BlockState block_state(&scope_, inner_block_scope);
6127
    scope()->set_start_position(scanner()->location().beg_pos);
6128

6129 6130 6131
    SourceRange body_range;
    SourceRangeScope range_scope(scanner(), &body_range);

6132
    body = ParseStatement(nullptr, nullptr, CHECK_OK);
6133
    scope()->set_end_position(scanner()->location().end_pos);
6134
    impl()->RecordIterationStatementSourceRange(loop, range_scope.Finalize());
6135 6136

    if (has_declarations) {
6137
      BlockT body_block = impl()->NullStatement();
6138 6139 6140
      impl()->DesugarBindingInForEachStatement(&for_info, &body_block,
                                               &each_variable, CHECK_OK);
      body_block->statements()->Add(body, zone());
6141
      body_block->set_scope(scope()->FinalizeBlockScope());
6142
      body = body_block;
6143
    } else {
6144
      Scope* block_scope = scope()->FinalizeBlockScope();
6145 6146 6147 6148
      DCHECK_NULL(block_scope);
      USE(block_scope);
    }
  }
6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159
  const bool finalize = true;
  StatementT final_loop = impl()->InitializeForOfStatement(
      loop, each_variable, iterable, body, finalize, IteratorType::kAsync,
      each_keyword_pos);

  if (!has_declarations) {
    Scope* for_scope = scope()->FinalizeBlockScope();
    DCHECK_NULL(for_scope);
    USE(for_scope);
    return final_loop;
  }
6160 6161

  BlockT init_block =
6162
      impl()->CreateForEachStatementTDZ(impl()->NullStatement(), for_info, ok);
6163

6164 6165
  scope()->set_end_position(scanner()->location().end_pos);
  Scope* for_scope = scope()->FinalizeBlockScope();
6166
  // Parsed for-in loop w/ variable declarations.
6167
  if (!impl()->IsNull(init_block)) {
6168 6169 6170 6171 6172 6173 6174 6175
    init_block->statements()->Add(final_loop, zone());
    init_block->set_scope(for_scope);
    return init_block;
  }
  DCHECK_NULL(for_scope);
  return final_loop;
}

6176
template <typename Impl>
6177 6178
void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto(
    Token::Value property) {
6179 6180
  if (property == Token::SMI || property == Token::NUMBER) return;

6181
  if (IsProto()) {
6182
    if (has_seen_proto_) {
6183 6184
      this->parser()->classifier()->RecordExpressionError(
          this->scanner()->location(), MessageTemplate::kDuplicateProto);
6185 6186 6187 6188 6189 6190
      return;
    }
    has_seen_proto_ = true;
  }
}

6191
template <typename Impl>
6192 6193 6194
void ParserBase<Impl>::ClassLiteralChecker::CheckClassMethodName(
    Token::Value property, PropertyKind type, bool is_generator, bool is_async,
    bool is_static, bool* ok) {
6195
  DCHECK(type == PropertyKind::kMethodProperty || IsAccessor(type));
6196 6197 6198

  if (property == Token::SMI || property == Token::NUMBER) return;

6199
  if (is_static) {
6200 6201 6202 6203 6204 6205
    if (IsPrototype()) {
      this->parser()->ReportMessage(MessageTemplate::kStaticPrototype);
      *ok = false;
      return;
    }
  } else if (IsConstructor()) {
6206
    if (is_generator || is_async || IsAccessor(type)) {
6207 6208
      MessageTemplate::Template msg =
          is_generator ? MessageTemplate::kConstructorIsGenerator
6209 6210
                       : is_async ? MessageTemplate::kConstructorIsAsync
                                  : MessageTemplate::kConstructorIsAccessor;
6211 6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 6222 6223
      this->parser()->ReportMessage(msg);
      *ok = false;
      return;
    }
    if (has_seen_constructor_) {
      this->parser()->ReportMessage(MessageTemplate::kDuplicateConstructor);
      *ok = false;
      return;
    }
    has_seen_constructor_ = true;
    return;
  }
}
6224

6225 6226 6227 6228 6229 6230 6231 6232 6233
template <typename Impl>
void ParserBase<Impl>::ClassLiteralChecker::CheckClassFieldName(bool is_static,
                                                                bool* ok) {
  if (is_static && IsPrototype()) {
    this->parser()->ReportMessage(MessageTemplate::kStaticPrototype);
    *ok = false;
    return;
  }

6234
  if (IsConstructor() || IsPrivateConstructor()) {
6235 6236 6237 6238 6239 6240
    this->parser()->ReportMessage(MessageTemplate::kConstructorClassField);
    *ok = false;
    return;
  }
}

6241 6242
#undef CHECK_OK
#undef CHECK_OK_CUSTOM
6243
#undef CHECK_OK_VOID
6244

6245 6246 6247
}  // namespace internal
}  // namespace v8

6248
#endif  // V8_PARSING_PARSER_BASE_H_