parser-base.h 231 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
#include <stdint.h>
9
#include <utility>
10 11
#include <vector>

12
#include "src/ast/ast-source-ranges.h"
13
#include "src/ast/ast.h"
14
#include "src/ast/scopes.h"
15
#include "src/base/flags.h"
lpy's avatar
lpy committed
16
#include "src/base/hashmap.h"
17
#include "src/base/v8-fallthrough.h"
18
#include "src/codegen/bailout-reason.h"
19
#include "src/common/globals.h"
20
#include "src/common/message-template.h"
21 22
#include "src/logging/counters.h"
#include "src/logging/log.h"
23
#include "src/objects/function-kind.h"
24
#include "src/parsing/expression-scope.h"
25
#include "src/parsing/func-name-inferrer.h"
26
#include "src/parsing/parse-info.h"
27 28
#include "src/parsing/scanner.h"
#include "src/parsing/token.h"
29
#include "src/utils/pointer-with-payload.h"
30
#include "src/zone/zone-chunk-list.h"
31 32 33 34 35 36 37 38 39 40

namespace v8 {
namespace internal {

enum FunctionNameValidity {
  kFunctionNameIsStrictReserved,
  kSkipFunctionNameCheck,
  kFunctionNameValidityUnknown
};

41 42 43 44
enum AllowLabelledFunctionStatement {
  kAllowLabelledFunctionStatement,
  kDisallowLabelledFunctionStatement,
};
45

46 47
enum ParsingArrowHeadFlag { kCertainlyNotArrowHead, kMaybeArrowHead };

48
enum class ParseFunctionFlag : uint8_t {
49
  kIsNormal = 0,
50 51
  kIsGenerator = 1 << 0,
  kIsAsync = 1 << 1
52 53
};

54
using ParseFunctionFlags = base::Flags<ParseFunctionFlag>;
55

56
struct FormalParametersBase {
57
  explicit FormalParametersBase(DeclarationScope* scope) : scope(scope) {}
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72

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

73
  DeclarationScope* scope;
74 75
  bool has_rest = false;
  bool is_simple = true;
76 77
  int function_length = 0;
  int arity = 0;
78 79
};

80
// Stack-allocated scope to collect source ranges from the parser.
81
class V8_NODISCARD SourceRangeScope final {
82
 public:
83 84 85
  SourceRangeScope(const Scanner* scanner, SourceRange* range)
      : scanner_(scanner), range_(range) {
    range_->start = scanner->peek_location().beg_pos;
86
    DCHECK_NE(range_->start, kNoSourcePosition);
87
    DCHECK_EQ(range_->end, kNoSourcePosition);
88 89
  }

90 91 92
  ~SourceRangeScope() {
    DCHECK_EQ(kNoSourcePosition, range_->end);
    range_->end = scanner_->location().end_pos;
93 94
    DCHECK_NE(range_->end, kNoSourcePosition);
  }
95 96

 private:
97
  const Scanner* scanner_;
98 99 100 101
  SourceRange* range_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(SourceRangeScope);
};
102

103
// ----------------------------------------------------------------------------
104 105
// The RETURN_IF_PARSE_ERROR macro is a convenient macro to enforce error
// handling for functions that may fail (by returning if there was an parser
106
// error).
107
//
108 109 110 111 112
// Usage:
//     foo = ParseFoo(); // may fail
//     RETURN_IF_PARSE_ERROR
//
//     SAFE_USE(foo);
113

114 115
#define RETURN_IF_PARSE_ERROR \
  if (has_error()) return impl()->NullStatement();
116

117 118 119 120 121
// 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:
//
122 123
//   // A structure template containing type definitions, needed to
//   // avoid a cyclic dependency.
124
//   template <typename Impl>
125 126
//   struct ParserTypes;
//
127 128 129 130 131
//   // 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>
132
//   class ParserBase { ... };
133 134 135 136 137
//
//   // And then, for each parser variant (e.g., parser, preparser, etc):
//   class Parser;
//
//   template <>
138
//   class ParserTypes<Parser> { ... };
139 140 141
//
//   class Parser : public ParserBase<Parser> { ... };
//
142 143 144 145 146 147 148 149 150 151
// 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:
//
152
// template <>
153 154 155 156 157 158 159 160 161
// 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;
162
//   typedef ClassLiteralProperty;
163
//   typedef ExpressionList;
164 165
//   typedef ObjectPropertyList;
//   typedef ClassPropertyList;
166
//   typedef FormalParameters;
167
//   typedef Statement;
168
//   typedef StatementList;
169
//   typedef Block;
170
//   typedef BreakableStatement;
171
//   typedef ForStatement;
172
//   typedef IterationStatement;
173 174
//   // For constructing objects returned by the traversing functions.
//   typedef Factory;
175 176 177
//   // For other implementation-specific tasks.
//   typedef Target;
//   typedef TargetScope;
178 179
// };

180
template <typename Impl>
181
struct ParserTypes;
182

183
enum class ParsePropertyKind : uint8_t {
184 185 186 187
  kAccessorGetter,
  kAccessorSetter,
  kValue,
  kShorthand,
188
  kAssign,
189 190
  kMethod,
  kClassField,
191
  kShorthandOrClassField,
192 193 194 195
  kSpread,
  kNotSet
};

196
template <typename Impl>
197
class ParserBase {
198
 public:
199
  // Shorten type names defined by ParserTypes<Impl>.
200 201 202 203 204 205 206 207 208 209 210
  using Types = ParserTypes<Impl>;
  using ExpressionScope = typename v8::internal::ExpressionScope<Types>;
  using ExpressionParsingScope =
      typename v8::internal::ExpressionParsingScope<Types>;
  using AccumulationScope = typename v8::internal::AccumulationScope<Types>;
  using ArrowHeadParsingScope =
      typename v8::internal::ArrowHeadParsingScope<Types>;
  using VariableDeclarationParsingScope =
      typename v8::internal::VariableDeclarationParsingScope<Types>;
  using ParameterDeclarationParsingScope =
      typename v8::internal::ParameterDeclarationParsingScope<Types>;
211 212

  // Return types for traversing functions.
213 214 215 216
  using BlockT = typename Types::Block;
  using BreakableStatementT = typename Types::BreakableStatement;
  using ClassLiteralPropertyT = typename Types::ClassLiteralProperty;
  using ClassPropertyListT = typename Types::ClassPropertyList;
217
  using ClassStaticElementListT = typename Types::ClassStaticElementList;
218 219 220 221 222 223 224 225 226 227 228 229
  using ExpressionT = typename Types::Expression;
  using ExpressionListT = typename Types::ExpressionList;
  using FormalParametersT = typename Types::FormalParameters;
  using ForStatementT = typename Types::ForStatement;
  using FunctionLiteralT = typename Types::FunctionLiteral;
  using IdentifierT = typename Types::Identifier;
  using IterationStatementT = typename Types::IterationStatement;
  using ObjectLiteralPropertyT = typename Types::ObjectLiteralProperty;
  using ObjectPropertyListT = typename Types::ObjectPropertyList;
  using StatementT = typename Types::Statement;
  using StatementListT = typename Types::StatementList;
  using SuspendExpressionT = typename Types::Suspend;
230
  // For constructing objects returned by the traversing functions.
231
  using FactoryT = typename Types::Factory;
232
  // Other implementation-specific tasks.
233 234 235 236
  using FuncNameInferrer = typename Types::FuncNameInferrer;
  using FuncNameInferrerState = typename Types::FuncNameInferrer::State;
  using SourceRange = typename Types::SourceRange;
  using SourceRangeScope = typename Types::SourceRangeScope;
237

238 239 240 241
  // 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); }

242
  ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit,
243
             v8::Extension* extension, AstValueFactory* ast_value_factory,
244
             PendingCompilationErrorHandler* pending_error_handler,
245
             RuntimeCallStats* runtime_call_stats, Logger* logger,
246
             UnoptimizedCompileFlags flags, bool parsing_on_main_thread)
247
      : scope_(nullptr),
248
        original_scope_(nullptr),
249
        function_state_(nullptr),
250
        extension_(extension),
251
        fni_(ast_value_factory),
252
        ast_value_factory_(ast_value_factory),
253
        ast_node_factory_(ast_value_factory, zone),
254
        runtime_call_stats_(runtime_call_stats),
255
        logger_(logger),
256
        parsing_on_main_thread_(parsing_on_main_thread),
257
        stack_limit_(stack_limit),
258
        pending_error_handler_(pending_error_handler),
259
        zone_(zone),
260
        expression_scope_(nullptr),
261
        scanner_(scanner),
262
        flags_(flags),
263
        function_literal_id_(0),
264
        default_eager_compile_hint_(FunctionLiteral::kShouldLazyCompile) {
265 266
    pointer_buffer_.reserve(32);
    variable_buffer_.reserve(32);
267
  }
268

269
  const UnoptimizedCompileFlags& flags() const { return flags_; }
270

271 272
  bool allow_eval_cache() const { return allow_eval_cache_; }
  void set_allow_eval_cache(bool allow) { allow_eval_cache_ = allow; }
273

274
  V8_INLINE bool has_error() const { return scanner()->has_parser_error(); }
275

276 277
  uintptr_t stack_limit() const { return stack_limit_; }

278 279
  void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; }

280 281 282 283 284 285 286 287 288
  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_;
  }

289 290 291
  int loop_nesting_depth() const {
    return function_state_->loop_nesting_depth();
  }
292 293 294 295 296 297 298
  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; }

299 300 301 302
  // 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.
303 304
  Zone* zone() const { return zone_; }

305
 protected:
306 307 308
  friend class v8::internal::ExpressionScope<ParserTypes<Impl>>;
  friend class v8::internal::ExpressionParsingScope<ParserTypes<Impl>>;
  friend class v8::internal::ArrowHeadParsingScope<ParserTypes<Impl>>;
309

310 311 312 313 314
  enum VariableDeclarationContext {
    kStatementListItem,
    kStatement,
    kForStatement
  };
315

316
  class ClassLiteralChecker;
317 318

  // ---------------------------------------------------------------------------
319 320 321 322
  // 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.
323
  class BlockState {
324
   public:
325 326 327
    BlockState(Scope** scope_stack, Scope* scope)
        : scope_stack_(scope_stack), outer_scope_(*scope_stack) {
      *scope_stack_ = scope;
328
    }
329

330 331
    BlockState(Zone* zone, Scope** scope_stack)
        : BlockState(scope_stack,
332
                     zone->New<Scope>(zone, *scope_stack, BLOCK_SCOPE)) {}
333

334
    ~BlockState() { *scope_stack_ = outer_scope_; }
335 336

   private:
337 338
    Scope** const scope_stack_;
    Scope* const outer_scope_;
339 340
  };

341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427
  // ---------------------------------------------------------------------------
  // Target is a support class to facilitate manipulation of the
  // Parser's target_stack_ (the stack of potential 'break' and
  // 'continue' statement targets). Upon construction, a new target is
  // added; it is removed upon destruction.

  // |labels| is a list of all labels that can be used as a target for break.
  // |own_labels| is a list of all labels that an iteration statement is
  // directly prefixed with, i.e. all the labels that a continue statement in
  // the body can use to continue this iteration statement. This is always a
  // subset of |labels|.
  //
  // Example: "l1: { l2: if (b) l3: l4: for (;;) s }"
  // labels() of the Block will be l1.
  // labels() of the ForStatement will be l2, l3, l4.
  // own_labels() of the ForStatement will be l3, l4.
  class Target {
   public:
    enum TargetType { TARGET_FOR_ANONYMOUS, TARGET_FOR_NAMED_ONLY };

    Target(ParserBase* parser, BreakableStatementT statement,
           ZonePtrList<const AstRawString>* labels,
           ZonePtrList<const AstRawString>* own_labels, TargetType target_type)
        : stack_(parser->function_state_->target_stack_address()),
          statement_(statement),
          labels_(labels),
          own_labels_(own_labels),
          target_type_(target_type),
          previous_(*stack_) {
      DCHECK_IMPLIES(Impl::IsIterationStatement(statement_),
                     target_type == Target::TARGET_FOR_ANONYMOUS);
      DCHECK_IMPLIES(!Impl::IsIterationStatement(statement_),
                     own_labels == nullptr);
      *stack_ = this;
    }

    ~Target() { *stack_ = previous_; }

    const Target* previous() const { return previous_; }
    const BreakableStatementT statement() const { return statement_; }
    const ZonePtrList<const AstRawString>* labels() const { return labels_; }
    const ZonePtrList<const AstRawString>* own_labels() const {
      return own_labels_;
    }
    bool is_iteration() const { return Impl::IsIterationStatement(statement_); }
    bool is_target_for_anonymous() const {
      return target_type_ == TARGET_FOR_ANONYMOUS;
    }

   private:
    Target** const stack_;
    const BreakableStatementT statement_;
    const ZonePtrList<const AstRawString>* const labels_;
    const ZonePtrList<const AstRawString>* const own_labels_;
    const TargetType target_type_;
    Target* const previous_;
  };

  Target* target_stack() { return *function_state_->target_stack_address(); }

  BreakableStatementT LookupBreakTarget(IdentifierT label) {
    bool anonymous = impl()->IsNull(label);
    for (const Target* t = target_stack(); t != nullptr; t = t->previous()) {
      if ((anonymous && t->is_target_for_anonymous()) ||
          (!anonymous &&
           ContainsLabel(t->labels(),
                         impl()->GetRawNameFromIdentifier(label)))) {
        return t->statement();
      }
    }
    return impl()->NullStatement();
  }

  IterationStatementT LookupContinueTarget(IdentifierT label) {
    bool anonymous = impl()->IsNull(label);
    for (const Target* t = target_stack(); t != nullptr; t = t->previous()) {
      if (!t->is_iteration()) continue;

      DCHECK(t->is_target_for_anonymous());
      if (anonymous || ContainsLabel(t->own_labels(),
                                     impl()->GetRawNameFromIdentifier(label))) {
        return impl()->AsIterationStatement(t->statement());
      }
    }
    return impl()->NullStatement();
  }

428
  class FunctionState final : public BlockState {
429
   public:
430 431
    FunctionState(FunctionState** function_state_stack, Scope** scope_stack,
                  DeclarationScope* scope);
432 433
    ~FunctionState();

434
    DeclarationScope* scope() const { return scope_->AsDeclarationScope(); }
435

436 437 438
    void AddProperty() { expected_property_count_++; }
    int expected_property_count() { return expected_property_count_; }

439 440 441 442 443
    void DisableOptimization(BailoutReason reason) {
      dont_optimize_reason_ = reason;
    }
    BailoutReason dont_optimize_reason() { return dont_optimize_reason_; }

444 445
    void AddSuspend() { suspend_count_++; }
    int suspend_count() const { return suspend_count_; }
446
    bool CanSuspend() const { return suspend_count_ > 0; }
447

448
    FunctionKind kind() const { return scope()->function_kind(); }
449

450 451
    bool next_function_is_likely_called() const {
      return next_function_is_likely_called_;
452 453
    }

454 455 456 457
    bool previous_function_was_likely_called() const {
      return previous_function_was_likely_called_;
    }

458
    void set_next_function_is_likely_called() {
459
      next_function_is_likely_called_ = !FLAG_max_lazy;
460 461
    }

462 463 464 465 466
    void RecordFunctionOrEvalCall() { contains_function_or_eval_ = true; }
    bool contains_function_or_eval() const {
      return contains_function_or_eval_;
    }

467
    class V8_NODISCARD FunctionOrEvalRecordingScope {
468 469
     public:
      explicit FunctionOrEvalRecordingScope(FunctionState* state)
470
          : state_and_prev_value_(state, state->contains_function_or_eval_) {
471 472 473
        state->contains_function_or_eval_ = false;
      }
      ~FunctionOrEvalRecordingScope() {
474
        bool found = state_and_prev_value_->contains_function_or_eval_;
475
        if (!found) {
476 477
          state_and_prev_value_->contains_function_or_eval_ =
              state_and_prev_value_.GetPayload();
478 479 480 481
        }
      }

     private:
482
      PointerWithPayload<FunctionState, bool, 1> state_and_prev_value_;
483 484
    };

485
    class V8_NODISCARD LoopScope final {
486 487 488 489 490 491 492 493 494 495 496 497 498 499
     public:
      explicit LoopScope(FunctionState* function_state)
          : function_state_(function_state) {
        function_state_->loop_nesting_depth_++;
      }

      ~LoopScope() { function_state_->loop_nesting_depth_--; }

     private:
      FunctionState* function_state_;
    };

    int loop_nesting_depth() const { return loop_nesting_depth_; }

500 501
    Target** target_stack_address() { return &target_stack_; }

502 503 504 505
   private:
    // Properties count estimation.
    int expected_property_count_;

506 507 508
    // How many suspends are needed for this function.
    int suspend_count_;

509 510 511
    // How deeply nested we currently are in this function.
    int loop_nesting_depth_ = 0;

512 513
    FunctionState** function_state_stack_;
    FunctionState* outer_function_state_;
514
    DeclarationScope* scope_;
515
    Target* target_stack_ = nullptr;  // for break, continue statements
516

517 518 519
    // A reason, if any, why this function should not be optimized.
    BailoutReason dont_optimize_reason_;

520
    // Record whether the next (=== immediately following) function literal is
521 522 523 524
    // 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.
525
    bool next_function_is_likely_called_;
526
    bool previous_function_was_likely_called_;
527

528 529 530
    // Track if a function or eval occurs within this FunctionState
    bool contains_function_or_eval_;

531
    friend Impl;
532 533
  };

534 535
  struct DeclarationDescriptor {
    VariableMode mode;
536
    VariableKind kind;
537 538 539 540 541 542
    int declaration_pos;
    int initialization_pos;
  };

  struct DeclarationParsingResult {
    struct Declaration {
543 544
      Declaration(ExpressionT pattern, ExpressionT initializer)
          : pattern(pattern), initializer(initializer) {
545 546
        DCHECK_IMPLIES(Impl::IsNull(pattern), Impl::IsNull(initializer));
      }
547 548 549

      ExpressionT pattern;
      ExpressionT initializer;
550
      int value_beg_pos = kNoSourcePosition;
551 552 553
    };

    DeclarationParsingResult()
554
        : first_initializer_loc(Scanner::Location::invalid()),
555 556 557
          bindings_loc(Scanner::Location::invalid()) {}

    DeclarationDescriptor descriptor;
558
    std::vector<Declaration> declarations;
559 560 561 562
    Scanner::Location first_initializer_loc;
    Scanner::Location bindings_loc;
  };

563 564 565
  struct CatchInfo {
   public:
    explicit CatchInfo(ParserBase* parser)
566 567 568
        : pattern(parser->impl()->NullExpression()),
          variable(nullptr),
          scope(nullptr) {}
569
    ExpressionT pattern;
570
    Variable* variable;
571 572 573
    Scope* scope;
  };

574 575 576 577 578
  struct ForInfo {
   public:
    explicit ForInfo(ParserBase* parser)
        : bound_names(1, parser->zone()),
          mode(ForEachStatement::ENUMERATE),
579
          position(kNoSourcePosition),
580
          parsing_result() {}
581
    ZonePtrList<const AstRawString> bound_names;
582
    ForEachStatement::VisitMode mode;
583
    int position;
584 585 586
    DeclarationParsingResult parsing_result;
  };

587 588 589
  struct ClassInfo {
   public:
    explicit ClassInfo(ParserBase* parser)
590
        : extends(parser->impl()->NullExpression()),
591 592
          public_members(parser->impl()->NewClassPropertyList(4)),
          private_members(parser->impl()->NewClassPropertyList(4)),
593
          static_elements(parser->impl()->NewClassStaticElementList(4)),
594
          instance_fields(parser->impl()->NewClassPropertyList(4)),
595
          constructor(parser->impl()->NullExpression()),
596
          has_seen_constructor(false),
597
          has_name_static_property(false),
598
          has_static_computed_names(false),
599
          has_static_elements(false),
600
          has_static_private_methods(false),
601
          has_static_blocks(false),
602
          has_instance_members(false),
603
          requires_brand(false),
604
          is_anonymous(false),
605
          has_private_methods(false),
606
          static_elements_scope(nullptr),
607
          instance_members_scope(nullptr),
608
          computed_field_count(0) {}
609
    ExpressionT extends;
610 611
    ClassPropertyListT public_members;
    ClassPropertyListT private_members;
612
    ClassStaticElementListT static_elements;
613
    ClassPropertyListT instance_fields;
614
    FunctionLiteralT constructor;
615

616 617 618
    bool has_seen_constructor;
    bool has_name_static_property;
    bool has_static_computed_names;
619
    bool has_static_elements;
620
    bool has_static_private_methods;
621
    bool has_static_blocks;
622
    bool has_instance_members;
623
    bool requires_brand;
624
    bool is_anonymous;
625
    bool has_private_methods;
626
    DeclarationScope* static_elements_scope;
627
    DeclarationScope* instance_members_scope;
628
    int computed_field_count;
629 630
    Variable* home_object_variable = nullptr;
    Variable* static_home_object_variable = nullptr;
631 632
  };

633 634 635
  enum class PropertyPosition { kObjectLiteral, kClassLiteral };
  struct ParsePropertyInfo {
   public:
636 637 638 639
    explicit ParsePropertyInfo(ParserBase* parser,
                               AccumulationScope* accumulation_scope = nullptr)
        : accumulation_scope(accumulation_scope),
          name(parser->impl()->NullIdentifier()),
640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678
          position(PropertyPosition::kClassLiteral),
          function_flags(ParseFunctionFlag::kIsNormal),
          kind(ParsePropertyKind::kNotSet),
          is_computed_name(false),
          is_private(false),
          is_static(false),
          is_rest(false) {}

    bool ParsePropertyKindFromToken(Token::Value token) {
      // 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 = ParsePropertyKind::kValue;
          return true;
        case Token::COMMA:
          kind = ParsePropertyKind::kShorthand;
          return true;
        case Token::RBRACE:
          kind = ParsePropertyKind::kShorthandOrClassField;
          return true;
        case Token::ASSIGN:
          kind = ParsePropertyKind::kAssign;
          return true;
        case Token::LPAREN:
          kind = ParsePropertyKind::kMethod;
          return true;
        case Token::MUL:
        case Token::SEMICOLON:
          kind = ParsePropertyKind::kClassField;
          return true;
        default:
          break;
      }
      return false;
    }

679
    AccumulationScope* accumulation_scope;
680 681 682 683 684 685 686 687 688 689
    IdentifierT name;
    PropertyPosition position;
    ParseFunctionFlags function_flags;
    ParsePropertyKind kind;
    bool is_computed_name;
    bool is_private;
    bool is_static;
    bool is_rest;
  };

690 691 692 693 694 695 696 697 698 699 700
  void DeclareLabel(ZonePtrList<const AstRawString>** labels,
                    ZonePtrList<const AstRawString>** own_labels,
                    const AstRawString* label) {
    if (ContainsLabel(*labels, label) || TargetStackContainsLabel(label)) {
      ReportMessage(MessageTemplate::kLabelRedeclaration, label);
      return;
    }

    // Add {label} to both {labels} and {own_labels}.
    if (*labels == nullptr) {
      DCHECK_NULL(*own_labels);
701 702 703 704
      *labels =
          zone()->template New<ZonePtrList<const AstRawString>>(1, zone());
      *own_labels =
          zone()->template New<ZonePtrList<const AstRawString>>(1, zone());
705 706
    } else {
      if (*own_labels == nullptr) {
707 708
        *own_labels =
            zone()->template New<ZonePtrList<const AstRawString>>(1, zone());
709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732
      }
    }
    (*labels)->Add(label, zone());
    (*own_labels)->Add(label, zone());
  }

  bool ContainsLabel(const ZonePtrList<const AstRawString>* labels,
                     const AstRawString* label) {
    DCHECK_NOT_NULL(label);
    if (labels != nullptr) {
      for (int i = labels->length(); i-- > 0;) {
        if (labels->at(i) == label) return true;
      }
    }
    return false;
  }

  bool TargetStackContainsLabel(const AstRawString* label) {
    for (const Target* t = target_stack(); t != nullptr; t = t->previous()) {
      if (ContainsLabel(t->labels(), label)) return true;
    }
    return false;
  }

733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748
  ClassLiteralProperty::Kind ClassPropertyKindFor(ParsePropertyKind kind) {
    switch (kind) {
      case ParsePropertyKind::kAccessorGetter:
        return ClassLiteralProperty::GETTER;
      case ParsePropertyKind::kAccessorSetter:
        return ClassLiteralProperty::SETTER;
      case ParsePropertyKind::kMethod:
        return ClassLiteralProperty::METHOD;
      case ParsePropertyKind::kClassField:
        return ClassLiteralProperty::FIELD;
      default:
        // Only returns for deterministic kinds
        UNREACHABLE();
    }
  }

749 750 751 752 753 754 755 756 757 758 759
  VariableMode GetVariableMode(ClassLiteralProperty::Kind kind) {
    switch (kind) {
      case ClassLiteralProperty::Kind::FIELD:
        return VariableMode::kConst;
      case ClassLiteralProperty::Kind::METHOD:
        return VariableMode::kPrivateMethod;
      case ClassLiteralProperty::Kind::GETTER:
        return VariableMode::kPrivateGetterOnly;
      case ClassLiteralProperty::Kind::SETTER:
        return VariableMode::kPrivateSetterOnly;
    }
760 761
  }

762 763 764
  const AstRawString* ClassFieldVariableName(AstValueFactory* ast_value_factory,
                                             int index) {
    std::string name = ".class-field-" + std::to_string(index);
765
    return ast_value_factory->GetOneByteString(name.c_str());
766 767
  }

768
  DeclarationScope* NewScriptScope(REPLMode repl_mode) const {
769 770
    return zone()->template New<DeclarationScope>(zone(), ast_value_factory(),
                                                  repl_mode);
771 772
  }

773
  DeclarationScope* NewVarblockScope() const {
774
    return zone()->template New<DeclarationScope>(zone(), scope(), BLOCK_SCOPE);
775 776
  }

777
  ModuleScope* NewModuleScope(DeclarationScope* parent) const {
778
    return zone()->template New<ModuleScope>(parent, ast_value_factory());
779 780
  }

781
  DeclarationScope* NewEvalScope(Scope* parent) const {
782
    return zone()->template New<DeclarationScope>(zone(), parent, EVAL_SCOPE);
783 784
  }

785
  ClassScope* NewClassScope(Scope* parent, bool is_anonymous) const {
786
    return zone()->template New<ClassScope>(zone(), parent, is_anonymous);
787 788
  }

789 790 791 792 793 794
  Scope* NewBlockScopeForObjectLiteral() {
    Scope* scope = NewScope(BLOCK_SCOPE);
    scope->set_is_block_scope_for_object_literal();
    return scope;
  }

795
  Scope* NewScope(ScopeType scope_type) const {
796 797 798 799 800 801
    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.
802
  Scope* NewScopeWithParent(Scope* parent, ScopeType scope_type) const {
Dan Elphick's avatar
Dan Elphick committed
803
    // Must always use the specific constructors for the blocklisted scope
804 805 806
    // types.
    DCHECK_NE(FUNCTION_SCOPE, scope_type);
    DCHECK_NE(SCRIPT_SCOPE, scope_type);
807
    DCHECK_NE(MODULE_SCOPE, scope_type);
808
    DCHECK_NOT_NULL(parent);
809
    return zone()->template New<Scope>(zone(), parent, scope_type);
810 811
  }

812 813 814
  // 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.
815 816
  DeclarationScope* NewFunctionScope(FunctionKind kind,
                                     Zone* parse_zone = nullptr) const {
817
    DCHECK(ast_value_factory());
818
    if (parse_zone == nullptr) parse_zone = zone();
819 820
    DeclarationScope* result = zone()->template New<DeclarationScope>(
        parse_zone, scope(), FUNCTION_SCOPE, kind);
821 822 823 824

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

825
    // TODO(verwaest): Move into the DeclarationScope constructor.
826 827 828
    if (!IsArrowFunction(kind)) {
      result->DeclareDefaultFunctionVariables(ast_value_factory());
    }
829 830 831
    return result;
  }

832 833 834 835 836 837 838
  V8_INLINE DeclarationScope* GetDeclarationScope() const {
    return scope()->GetDeclarationScope();
  }
  V8_INLINE DeclarationScope* GetClosureScope() const {
    return scope()->GetClosureScope();
  }

839 840 841 842 843
  VariableProxy* NewRawVariable(const AstRawString* name, int pos) {
    return factory()->ast_node_factory()->NewVariableProxy(
        name, NORMAL_VARIABLE, pos);
  }

844 845 846 847 848 849 850 851 852 853 854
  VariableProxy* NewUnresolved(const AstRawString* name) {
    return scope()->NewUnresolved(factory()->ast_node_factory(), name,
                                  scanner()->location().beg_pos);
  }

  VariableProxy* NewUnresolved(const AstRawString* name, int begin_pos,
                               VariableKind kind = NORMAL_VARIABLE) {
    return scope()->NewUnresolved(factory()->ast_node_factory(), name,
                                  begin_pos, kind);
  }

855 856
  Scanner* scanner() const { return scanner_; }
  AstValueFactory* ast_value_factory() const { return ast_value_factory_; }
857 858
  int position() const { return scanner_->location().beg_pos; }
  int peek_position() const { return scanner_->peek_location().beg_pos; }
859 860
  int end_position() const { return scanner_->location().end_pos; }
  int peek_end_position() const { return scanner_->peek_location().end_pos; }
861 862 863
  bool stack_overflow() const {
    return pending_error_handler()->stack_overflow();
  }
864 865 866 867
  void set_stack_overflow() {
    scanner_->set_parser_error();
    pending_error_handler()->set_stack_overflow();
  }
868 869
  void CheckStackOverflow() {
    // Any further calls to Next or peek will return the illegal token.
870
    if (GetCurrentStackPosition() < stack_limit_) set_stack_overflow();
871
  }
872

873
  V8_INLINE Token::Value peek() { return scanner()->peek(); }
874

875 876 877
  // Returns the position past the following semicolon (if it exists), and the
  // position past the end of the current token otherwise.
  int PositionAfterSemicolon() {
878
    return (peek() == Token::SEMICOLON) ? peek_end_position() : end_position();
879 880
  }

881
  V8_INLINE Token::Value PeekAhead() { return scanner()->PeekAhead(); }
882

883
  V8_INLINE Token::Value Next() { return scanner()->Next(); }
884

885
  V8_INLINE void Consume(Token::Value token) {
886
    Token::Value next = scanner()->Next();
887 888
    USE(next);
    USE(token);
889
    DCHECK_IMPLIES(!has_error(), next == token);
890 891
  }

892 893
  V8_INLINE bool Check(Token::Value token) {
    Token::Value next = scanner()->peek();
894 895 896 897 898 899 900
    if (next == token) {
      Consume(next);
      return true;
    }
    return false;
  }

901
  void Expect(Token::Value token) {
902
    Token::Value next = Next();
903
    if (V8_UNLIKELY(next != token)) {
904 905 906 907
      ReportUnexpectedToken(next);
    }
  }

908
  void ExpectSemicolon() {
909 910 911
    // Check for automatic semicolon insertion according to
    // the rules given in ECMA-262, section 7.9, page 21.
    Token::Value tok = peek();
912
    if (V8_LIKELY(tok == Token::SEMICOLON)) {
913 914 915
      Next();
      return;
    }
916 917
    if (V8_LIKELY(scanner()->HasLineTerminatorBeforeNext() ||
                  Token::IsAutoSemicolon(tok))) {
918 919
      return;
    }
920

921 922
    if (scanner()->current_token() == Token::AWAIT && !is_async_function()) {
      ReportMessageAt(scanner()->location(),
923 924 925
                      flags().allow_harmony_top_level_await()
                          ? MessageTemplate::kAwaitNotInAsyncContext
                          : MessageTemplate::kAwaitNotInAsyncFunction);
926 927 928
      return;
    }

929
    ReportUnexpectedToken(Next());
930 931
  }

932
  bool peek_any_identifier() { return Token::IsAnyIdentifier(peek()); }
933

934 935
  bool PeekContextualKeyword(const AstRawString* name) {
    return peek() == Token::IDENTIFIER &&
936
           !scanner()->next_literal_contains_escapes() &&
937 938 939 940 941
           scanner()->NextSymbol(ast_value_factory()) == name;
  }

  bool CheckContextualKeyword(const AstRawString* name) {
    if (PeekContextualKeyword(name)) {
942 943 944 945 946 947
      Consume(Token::IDENTIFIER);
      return true;
    }
    return false;
  }

948 949
  void ExpectContextualKeyword(const AstRawString* name,
                               const char* fullname = nullptr, int pos = -1) {
950
    Expect(Token::IDENTIFIER);
951
    if (V8_UNLIKELY(scanner()->CurrentSymbol(ast_value_factory()) != name)) {
952 953
      ReportUnexpectedToken(scanner()->current_token());
    }
954 955 956 957 958 959 960 961 962
    if (V8_UNLIKELY(scanner()->literal_contains_escapes())) {
      const char* full = fullname == nullptr
                             ? reinterpret_cast<const char*>(name->raw_data())
                             : fullname;
      int start = pos == -1 ? position() : pos;
      impl()->ReportMessageAt(Scanner::Location(start, end_position()),
                              MessageTemplate::kInvalidEscapedMetaProperty,
                              full);
    }
963 964
  }

965
  bool CheckInOrOf(ForEachStatement::VisitMode* visit_mode) {
966
    if (Check(Token::IN)) {
967
      *visit_mode = ForEachStatement::ENUMERATE;
968
      return true;
969
    } else if (CheckContextualKeyword(ast_value_factory()->of_string())) {
970 971 972 973 974 975
      *visit_mode = ForEachStatement::ITERATE;
      return true;
    }
    return false;
  }

976
  bool PeekInOrOf() {
977 978
    return peek() == Token::IN ||
           PeekContextualKeyword(ast_value_factory()->of_string());
979 980
  }

981
  // Checks whether an octal literal was last seen between beg_pos and end_pos.
982
  // Only called for strict mode strings.
983
  void CheckStrictOctalLiteral(int beg_pos, int end_pos) {
984 985 986
    Scanner::Location octal = scanner()->octal_position();
    if (octal.IsValid() && beg_pos <= octal.beg_pos &&
        octal.end_pos <= end_pos) {
987
      MessageTemplate message = scanner()->octal_message();
988
      DCHECK_NE(message, MessageTemplate::kNone);
989
      impl()->ReportMessageAt(octal, message);
990
      scanner()->clear_octal_position();
991 992 993
      if (message == MessageTemplate::kStrictDecimalWithLeadingZero) {
        impl()->CountUsage(v8::Isolate::kDecimalWithLeadingZeroInStrictMode);
      }
994 995 996
    }
  }

997
  // Checks if an octal literal or an invalid hex or unicode escape sequence
998 999 1000
  // 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.
1001
  inline bool CheckTemplateEscapes(bool should_throw) {
1002
    DCHECK(Token::IsTemplate(scanner()->current_token()));
1003
    if (!scanner()->has_invalid_template_escape()) return true;
1004

1005 1006 1007 1008 1009
    // Handle error case(s)
    if (should_throw) {
      impl()->ReportMessageAt(scanner()->invalid_template_escape_location(),
                              scanner()->invalid_template_escape_message());
    }
1010
    scanner()->clear_invalid_template_escape_message();
1011
    return should_throw;
1012 1013
  }

1014 1015 1016 1017
  ExpressionT ParsePossibleDestructuringSubPattern(AccumulationScope* scope);
  void ClassifyParameter(IdentifierT parameter, int beg_pos, int end_pos);
  void ClassifyArrowParameter(AccumulationScope* accumulation_scope,
                              int position, ExpressionT parameter);
1018 1019 1020 1021 1022

  // 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,
1023
                         const Scanner::Location& function_name_loc) {
1024
    if (impl()->IsNull(function_name)) return;
1025 1026 1027 1028
    if (function_name_validity == kSkipFunctionNameCheck) return;
    // The function name needs to be checked in strict mode.
    if (is_sloppy(language_mode)) return;

1029
    if (impl()->IsEvalOrArguments(function_name)) {
1030
      impl()->ReportMessageAt(function_name_loc,
1031 1032 1033 1034
                              MessageTemplate::kStrictEvalArguments);
      return;
    }
    if (function_name_validity == kFunctionNameIsStrictReserved) {
1035
      impl()->ReportMessageAt(function_name_loc,
1036 1037 1038 1039 1040
                              MessageTemplate::kUnexpectedStrictReserved);
      return;
    }
  }

1041
  typename Types::Factory* factory() { return &ast_node_factory_; }
1042

1043 1044 1045
  DeclarationScope* GetReceiverScope() const {
    return scope()->GetReceiverScope();
  }
1046
  LanguageMode language_mode() { return scope()->language_mode(); }
1047 1048 1049 1050
  void RaiseLanguageMode(LanguageMode mode) {
    LanguageMode old = scope()->language_mode();
    impl()->SetLanguageMode(scope(), old > mode ? old : mode);
  }
1051 1052 1053
  bool is_generator() const {
    return IsGeneratorFunction(function_state_->kind());
  }
1054
  bool is_async_function() const {
1055 1056
    return IsAsyncFunction(function_state_->kind());
  }
1057 1058 1059
  bool is_async_generator() const {
    return IsAsyncGeneratorFunction(function_state_->kind());
  }
1060 1061
  bool is_resumable() const {
    return IsResumableFunction(function_state_->kind());
1062
  }
1063 1064 1065 1066
  bool is_class_static_block() const {
    return function_state_->kind() ==
           FunctionKind::kClassStaticInitializerFunction;
  }
1067
  bool is_await_allowed() const {
1068
    return is_async_function() || (flags().allow_harmony_top_level_await() &&
1069 1070
                                   IsModule(function_state_->kind()));
  }
1071 1072 1073 1074 1075 1076 1077
  const PendingCompilationErrorHandler* pending_error_handler() const {
    return pending_error_handler_;
  }
  PendingCompilationErrorHandler* pending_error_handler() {
    return pending_error_handler_;
  }

1078
  // Report syntax errors.
1079
  V8_NOINLINE void ReportMessage(MessageTemplate message) {
1080
    Scanner::Location source_location = scanner()->location();
1081
    impl()->ReportMessageAt(source_location, message,
1082
                            static_cast<const char*>(nullptr));
1083 1084
  }

1085
  template <typename T>
1086
  V8_NOINLINE void ReportMessage(MessageTemplate message, T arg) {
1087
    Scanner::Location source_location = scanner()->location();
1088
    impl()->ReportMessageAt(source_location, message, arg);
1089 1090
  }

1091
  V8_NOINLINE void ReportMessageAt(Scanner::Location location,
1092
                                   MessageTemplate message) {
1093
    impl()->ReportMessageAt(location, message,
1094
                            static_cast<const char*>(nullptr));
1095 1096
  }

1097
  V8_NOINLINE void ReportUnexpectedToken(Token::Value token);
1098

1099
  void ValidateFormalParameters(LanguageMode language_mode,
1100
                                const FormalParametersT& parameters,
1101
                                bool allow_duplicates) {
1102 1103
    if (!allow_duplicates) parameters.ValidateDuplicate(impl());
    if (is_strict(language_mode)) parameters.ValidateStrictMode(impl());
1104 1105
  }

1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125
  // Needs to be called if the reference needs to be available from the current
  // point. It causes the receiver to be context allocated if necessary.
  // Returns the receiver variable that we're referencing.
  V8_INLINE Variable* UseThis() {
    DeclarationScope* closure_scope = scope()->GetClosureScope();
    DeclarationScope* receiver_scope = closure_scope->GetReceiverScope();
    Variable* var = receiver_scope->receiver();
    var->set_is_used();
    if (closure_scope == receiver_scope) {
      // It's possible that we're parsing the head of an arrow function, in
      // which case we haven't realized yet that closure_scope !=
      // receiver_scope. Mark through the ExpressionScope for now.
      expression_scope()->RecordThisUse();
    } else {
      closure_scope->set_has_this_reference();
      var->ForceContextAllocation();
    }
    return var;
  }

1126
  V8_INLINE IdentifierT ParseAndClassifyIdentifier(Token::Value token);
1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137
  // Parses an identifier or a strict mode future reserved word. Allows passing
  // in function_kind for the case of parsing the identifier in a function
  // expression, where the relevant "function_kind" bit is of the function being
  // parsed, not the containing function.
  V8_INLINE IdentifierT ParseIdentifier(FunctionKind function_kind);
  V8_INLINE IdentifierT ParseIdentifier() {
    return ParseIdentifier(function_state_->kind());
  }
  // Same as above but additionally disallows 'eval' and 'arguments' in strict
  // mode.
  IdentifierT ParseNonRestrictedIdentifier();
1138

1139 1140
  // This method should be used to ambiguously parse property names that can
  // become destructuring identifiers.
1141
  V8_INLINE IdentifierT ParsePropertyName();
1142

1143
  ExpressionT ParsePropertyOrPrivatePropertyName();
1144

1145
  ExpressionT ParseRegExpLiteral();
1146

1147 1148
  ExpressionT ParseBindingPattern();
  ExpressionT ParsePrimaryExpression();
1149

1150 1151
  // Use when parsing an expression that is known to not be a pattern or part of
  // a pattern.
1152
  V8_INLINE ExpressionT ParseExpression();
1153
  V8_INLINE ExpressionT ParseAssignmentExpression();
1154

1155 1156 1157 1158 1159
  // These methods do not wrap the parsing of the expression inside a new
  // expression_scope; they use the outer expression_scope instead. They 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
1160 1161
  // "CoverParenthesizedExpressionAndArrowParameterList" in the ES 2017
  // specification).
1162
  ExpressionT ParseExpressionCoverGrammar();
1163 1164 1165
  ExpressionT ParseAssignmentExpressionCoverGrammar();

  ExpressionT ParseArrowParametersWithRest(ExpressionListT* list,
1166 1167
                                           AccumulationScope* scope,
                                           int seen_variables);
1168

1169
  ExpressionT ParseArrayLiteral();
1170

1171
  inline static bool IsAccessor(ParsePropertyKind kind) {
1172 1173
    return base::IsInRange(kind, ParsePropertyKind::kAccessorGetter,
                           ParsePropertyKind::kAccessorSetter);
1174 1175
  }

1176
  ExpressionT ParseProperty(ParsePropertyInfo* prop_info);
1177
  ExpressionT ParseObjectLiteral();
1178
  ClassLiteralPropertyT ParseClassPropertyDefinition(
1179
      ClassInfo* class_info, ParsePropertyInfo* prop_info, bool has_extends);
1180 1181 1182 1183
  void CheckClassFieldName(IdentifierT name, bool is_static);
  void CheckClassMethodName(IdentifierT name, ParsePropertyKind type,
                            ParseFunctionFlags flags, bool is_static,
                            bool* has_seen_constructor);
1184 1185
  ExpressionT ParseMemberInitializer(ClassInfo* class_info, int beg_pos,
                                     bool is_static);
1186
  BlockT ParseClassStaticBlock(ClassInfo* class_info);
1187 1188
  ObjectLiteralPropertyT ParseObjectPropertyDefinition(
      ParsePropertyInfo* prop_info, bool* has_seen_proto);
1189 1190 1191
  void ParseArguments(
      ExpressionListT* args, bool* has_spread,
      ParsingArrowHeadFlag maybe_arrow = kCertainlyNotArrowHead);
1192

1193 1194 1195
  ExpressionT ParseYieldExpression();
  V8_INLINE ExpressionT ParseConditionalExpression();
  ExpressionT ParseConditionalContinuation(ExpressionT expression, int pos);
1196 1197
  ExpressionT ParseLogicalExpression();
  ExpressionT ParseCoalesceExpression(ExpressionT expression);
1198 1199
  ExpressionT ParseBinaryContinuation(ExpressionT x, int prec, int prec1);
  V8_INLINE ExpressionT ParseBinaryExpression(int prec);
1200
  ExpressionT ParseUnaryOrPrefixExpression();
1201 1202 1203
  ExpressionT ParseAwaitExpression();
  V8_INLINE ExpressionT ParseUnaryExpression();
  V8_INLINE ExpressionT ParsePostfixExpression();
1204 1205
  V8_NOINLINE ExpressionT ParsePostfixContinuation(ExpressionT expression,
                                                   int lhs_beg_pos);
1206 1207 1208 1209 1210
  V8_INLINE ExpressionT ParseLeftHandSideExpression();
  ExpressionT ParseLeftHandSideContinuation(ExpressionT expression);
  ExpressionT ParseMemberWithPresentNewPrefixesExpression();
  ExpressionT ParseFunctionExpression();
  V8_INLINE ExpressionT ParseMemberExpression();
1211
  V8_INLINE ExpressionT
1212
  ParseMemberExpressionContinuation(ExpressionT expression) {
1213
    if (!Token::IsMember(peek())) return expression;
1214
    return DoParseMemberExpressionContinuation(expression);
1215
  }
1216
  ExpressionT DoParseMemberExpressionContinuation(ExpressionT expression);
1217

1218
  ExpressionT ParseArrowFunctionLiteral(const FormalParametersT& parameters);
1219
  void ParseAsyncFunctionBody(Scope* scope, StatementListT* body);
1220
  ExpressionT ParseAsyncFunctionLiteral();
1221 1222 1223
  ExpressionT ParseClassLiteral(IdentifierT name,
                                Scanner::Location class_name_location,
                                bool name_is_strict_reserved,
1224 1225
                                int class_token_pos);
  ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool tagged);
1226
  ExpressionT ParseSuperExpression();
1227 1228 1229 1230 1231
  ExpressionT ParseImportExpressions();
  ExpressionT ParseNewTargetExpression();

  V8_INLINE void ParseFormalParameter(FormalParametersT* parameters);
  void ParseFormalParameterList(FormalParametersT* parameters);
1232 1233
  void CheckArityRestrictions(int param_count, FunctionKind function_type,
                              bool has_rest, int formals_start_pos,
1234
                              int formals_end_pos);
1235

1236
  void ParseVariableDeclarations(VariableDeclarationContext var_context,
1237 1238
                                 DeclarationParsingResult* parsing_result,
                                 ZonePtrList<const AstRawString>* names);
1239
  StatementT ParseAsyncFunctionDeclaration(
1240 1241
      ZonePtrList<const AstRawString>* names, bool default_export);
  StatementT ParseFunctionDeclaration();
1242
  StatementT ParseHoistableDeclaration(ZonePtrList<const AstRawString>* names,
1243
                                       bool default_export);
1244
  StatementT ParseHoistableDeclaration(int pos, ParseFunctionFlags flags,
1245
                                       ZonePtrList<const AstRawString>* names,
1246
                                       bool default_export);
1247
  StatementT ParseClassDeclaration(ZonePtrList<const AstRawString>* names,
1248 1249
                                   bool default_export);
  StatementT ParseNativeDeclaration();
1250

1251 1252
  // Whether we're parsing a single-expression arrow function or something else.
  enum class FunctionBodyType { kExpression, kBlock };
1253
  // Consumes the ending }.
1254
  void ParseFunctionBody(StatementListT* body, IdentifierT function_name,
1255 1256
                         int pos, const FormalParametersT& parameters,
                         FunctionKind kind,
1257
                         FunctionSyntaxKind function_syntax_kind,
1258
                         FunctionBodyType body_type);
1259

1260 1261 1262 1263 1264 1265 1266 1267 1268
  // Check if the scope has conflicting var/let declarations from different
  // scopes. This covers for example
  //
  // function f() { { { var x; } let x; } }
  // function g() { { var x; let x; } }
  //
  // The var declarations are hoisted to the function scope, but originate from
  // a scope where the name has also been let bound or the var declaration is
  // hoisted over such a scope.
1269
  void CheckConflictingVarDeclarations(DeclarationScope* scope) {
1270
    if (has_error()) return;
1271 1272 1273 1274 1275 1276
    bool allowed_catch_binding_var_redeclaration = false;
    Declaration* decl = scope->CheckConflictingVarDeclarations(
        &allowed_catch_binding_var_redeclaration);
    if (allowed_catch_binding_var_redeclaration) {
      impl()->CountUsage(v8::Isolate::kVarRedeclaredCatchBinding);
    }
1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289
    if (decl != nullptr) {
      // In ES6, conflicting variable bindings are early errors.
      const AstRawString* name = decl->var()->raw_name();
      int position = decl->position();
      Scanner::Location location =
          position == kNoSourcePosition
              ? Scanner::Location::invalid()
              : Scanner::Location(position, position + 1);
      impl()->ReportMessageAt(location, MessageTemplate::kVarRedeclaration,
                              name);
    }
  }

1290 1291 1292 1293
  // 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.
1294
  V8_INLINE void ParseStatementList(StatementListT* body,
1295
                                    Token::Value end_token);
1296
  StatementT ParseStatementListItem();
1297 1298

  StatementT ParseStatement(ZonePtrList<const AstRawString>* labels,
1299
                            ZonePtrList<const AstRawString>* own_labels) {
1300
    return ParseStatement(labels, own_labels,
1301
                          kDisallowLabelledFunctionStatement);
1302
  }
1303
  StatementT ParseStatement(ZonePtrList<const AstRawString>* labels,
1304
                            ZonePtrList<const AstRawString>* own_labels,
1305
                            AllowLabelledFunctionStatement allow_function);
1306 1307
  BlockT ParseBlock(ZonePtrList<const AstRawString>* labels,
                    Scope* block_scope);
1308
  BlockT ParseBlock(ZonePtrList<const AstRawString>* labels);
1309

1310 1311 1312
  // Parse a SubStatement in strict mode, or with an extra block scope in
  // sloppy mode to handle
  // ES#sec-functiondeclarations-in-ifstatement-statement-clauses
1313
  StatementT ParseScopedStatement(ZonePtrList<const AstRawString>* labels);
1314 1315

  StatementT ParseVariableStatement(VariableDeclarationContext var_context,
1316
                                    ZonePtrList<const AstRawString>* names);
1317 1318

  // Magical syntax support.
1319
  ExpressionT ParseV8Intrinsic();
1320

1321
  StatementT ParseDebuggerStatement();
1322

1323
  StatementT ParseExpressionOrLabelledStatement(
1324
      ZonePtrList<const AstRawString>* labels,
1325
      ZonePtrList<const AstRawString>* own_labels,
1326 1327 1328 1329 1330 1331
      AllowLabelledFunctionStatement allow_function);
  StatementT ParseIfStatement(ZonePtrList<const AstRawString>* labels);
  StatementT ParseContinueStatement();
  StatementT ParseBreakStatement(ZonePtrList<const AstRawString>* labels);
  StatementT ParseReturnStatement();
  StatementT ParseWithStatement(ZonePtrList<const AstRawString>* labels);
1332
  StatementT ParseDoWhileStatement(ZonePtrList<const AstRawString>* labels,
1333
                                   ZonePtrList<const AstRawString>* own_labels);
1334
  StatementT ParseWhileStatement(ZonePtrList<const AstRawString>* labels,
1335 1336 1337 1338
                                 ZonePtrList<const AstRawString>* own_labels);
  StatementT ParseThrowStatement();
  StatementT ParseSwitchStatement(ZonePtrList<const AstRawString>* labels);
  V8_INLINE StatementT ParseTryStatement();
1339
  StatementT ParseForStatement(ZonePtrList<const AstRawString>* labels,
1340
                               ZonePtrList<const AstRawString>* own_labels);
1341
  StatementT ParseForEachStatementWithDeclarations(
1342
      int stmt_pos, ForInfo* for_info, ZonePtrList<const AstRawString>* labels,
1343
      ZonePtrList<const AstRawString>* own_labels, Scope* inner_block_scope);
1344 1345
  StatementT ParseForEachStatementWithoutDeclarations(
      int stmt_pos, ExpressionT expression, int lhs_beg_pos, int lhs_end_pos,
1346
      ForInfo* for_info, ZonePtrList<const AstRawString>* labels,
1347
      ZonePtrList<const AstRawString>* own_labels);
1348

1349 1350
  // Parse a C-style for loop: 'for (<init>; <cond>; <next>) { ... }'
  // "for (<init>;" is assumed to have been parser already.
1351 1352 1353
  ForStatementT ParseStandardForLoop(
      int stmt_pos, ZonePtrList<const AstRawString>* labels,
      ZonePtrList<const AstRawString>* own_labels, ExpressionT* cond,
1354
      StatementT* next, StatementT* body);
1355
  // Same as the above, but handles those cases where <init> is a
1356 1357 1358
  // lexical variable declaration.
  StatementT ParseStandardForLoopWithLexicalDeclarations(
      int stmt_pos, StatementT init, ForInfo* for_info,
1359
      ZonePtrList<const AstRawString>* labels,
1360 1361 1362 1363
      ZonePtrList<const AstRawString>* own_labels);
  StatementT ParseForAwaitStatement(
      ZonePtrList<const AstRawString>* labels,
      ZonePtrList<const AstRawString>* own_labels);
1364

1365 1366 1367 1368
  V8_INLINE bool IsLet(const AstRawString* identifier) const {
    return identifier == ast_value_factory()->let_string();
  }

1369 1370 1371 1372 1373
  bool IsNextLetKeyword();

  // 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.
1374 1375
  // Modern language features can be exempted from this hack by passing
  // early_error = true.
1376 1377
  ExpressionT RewriteInvalidReferenceExpression(ExpressionT expression,
                                                int beg_pos, int end_pos,
1378 1379
                                                MessageTemplate message,
                                                bool early_error);
1380 1381 1382 1383

  bool IsValidReferenceExpression(ExpressionT expression);

  bool IsAssignableIdentifier(ExpressionT expression) {
1384
    if (!impl()->IsIdentifier(expression)) return false;
1385
    if (is_strict(language_mode()) &&
1386
        impl()->IsEvalOrArguments(impl()->AsIdentifier(expression))) {
1387 1388 1389 1390 1391
      return false;
    }
    return true;
  }

1392 1393 1394 1395
  enum SubFunctionKind { kFunction, kNonStaticMethod, kStaticMethod };

  FunctionKind FunctionKindForImpl(SubFunctionKind sub_function_kind,
                                   ParseFunctionFlags flags) {
1396 1397
    static const FunctionKind kFunctionKinds[][2][2] = {
        {
1398
            // SubFunctionKind::kNormalFunction
1399 1400 1401 1402 1403 1404 1405
            {// is_generator=false
             FunctionKind::kNormalFunction, FunctionKind::kAsyncFunction},
            {// is_generator=true
             FunctionKind::kGeneratorFunction,
             FunctionKind::kAsyncGeneratorFunction},
        },
        {
1406
            // SubFunctionKind::kNonStaticMethod
1407 1408 1409 1410 1411
            {// is_generator=false
             FunctionKind::kConciseMethod, FunctionKind::kAsyncConciseMethod},
            {// is_generator=true
             FunctionKind::kConciseGeneratorMethod,
             FunctionKind::kAsyncConciseGeneratorMethod},
1412 1413 1414 1415 1416 1417 1418 1419 1420
        },
        {
            // SubFunctionKind::kStaticMethod
            {// is_generator=false
             FunctionKind::kStaticConciseMethod,
             FunctionKind::kStaticAsyncConciseMethod},
            {// is_generator=true
             FunctionKind::kStaticConciseGeneratorMethod,
             FunctionKind::kStaticAsyncConciseGeneratorMethod},
1421
        }};
1422
    return kFunctionKinds[sub_function_kind]
1423 1424
                         [(flags & ParseFunctionFlag::kIsGenerator) != 0]
                         [(flags & ParseFunctionFlag::kIsAsync) != 0];
1425 1426
  }

1427
  inline FunctionKind FunctionKindFor(ParseFunctionFlags flags) {
1428
    return FunctionKindForImpl(SubFunctionKind::kFunction, flags);
1429 1430
  }

1431 1432 1433 1434
  inline FunctionKind MethodKindFor(bool is_static, ParseFunctionFlags flags) {
    return FunctionKindForImpl(is_static ? SubFunctionKind::kStaticMethod
                                         : SubFunctionKind::kNonStaticMethod,
                               flags);
1435 1436
  }

1437 1438 1439
  // 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.
1440
  Call::PossiblyEval CheckPossibleEvalCall(ExpressionT expression,
1441
                                           bool is_optional_call,
1442
                                           Scope* scope) {
1443 1444
    if (impl()->IsIdentifier(expression) &&
        impl()->IsEval(impl()->AsIdentifier(expression)) && !is_optional_call) {
1445
      function_state_->RecordFunctionOrEvalCall();
1446 1447
      scope->RecordEvalCall();

1448
      return Call::IS_POSSIBLY_EVAL;
1449
    }
1450
    return Call::NOT_EVAL;
1451 1452
  }

1453 1454
  // Convenience method which determines the type of return statement to emit
  // depending on the current function type.
1455 1456
  inline StatementT BuildReturnStatement(ExpressionT expr, int pos,
                                         int end_pos = kNoSourcePosition) {
1457
    if (impl()->IsNull(expr)) {
1458
      expr = factory()->NewUndefinedLiteral(kNoSourcePosition);
1459 1460 1461 1462
    } 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);
1463
      function_state_->AddSuspend();
1464 1465 1466 1467 1468
    }
    if (is_async_function()) {
      return factory()->NewAsyncReturnStatement(expr, pos, end_pos);
    }
    return factory()->NewReturnStatement(expr, pos, end_pos);
1469 1470
  }

1471
  SourceTextModuleDescriptor* module() const {
1472
    return scope()->AsModuleScope()->module();
1473
  }
1474
  Scope* scope() const { return scope_; }
1475

1476 1477 1478 1479 1480
  // Stack of expression expression_scopes.
  // The top of the stack is always pointed to by expression_scope().
  V8_INLINE ExpressionScope* expression_scope() const {
    DCHECK_NOT_NULL(expression_scope_);
    return expression_scope_;
1481 1482
  }

1483 1484 1485 1486 1487
  bool MaybeParsingArrowhead() const {
    return expression_scope_ != nullptr &&
           expression_scope_->has_possible_arrow_parameter_in_scope_chain();
  }

1488
  class V8_NODISCARD AcceptINScope final {
1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501
   public:
    AcceptINScope(ParserBase* parser, bool accept_IN)
        : parser_(parser), previous_accept_IN_(parser->accept_IN_) {
      parser_->accept_IN_ = accept_IN;
    }

    ~AcceptINScope() { parser_->accept_IN_ = previous_accept_IN_; }

   private:
    ParserBase* parser_;
    bool previous_accept_IN_;
  };

1502
  class V8_NODISCARD ParameterParsingScope {
1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515
   public:
    ParameterParsingScope(Impl* parser, FormalParametersT* parameters)
        : parser_(parser), parent_parameters_(parser_->parameters_) {
      parser_->parameters_ = parameters;
    }

    ~ParameterParsingScope() { parser_->parameters_ = parent_parameters_; }

   private:
    Impl* parser_;
    FormalParametersT* parent_parameters_;
  };

1516
  class V8_NODISCARD FunctionParsingScope {
1517
   public:
1518
    explicit FunctionParsingScope(Impl* parser)
1519 1520 1521 1522
        : parser_(parser), expression_scope_(parser_->expression_scope_) {
      parser_->expression_scope_ = nullptr;
    }

1523
    ~FunctionParsingScope() { parser_->expression_scope_ = expression_scope_; }
1524 1525 1526 1527 1528

   private:
    Impl* parser_;
    ExpressionScope* expression_scope_;
  };
1529

1530
  std::vector<void*>* pointer_buffer() { return &pointer_buffer_; }
1531 1532 1533
  std::vector<std::pair<VariableProxy*, int>>* variable_buffer() {
    return &variable_buffer_;
  }
1534

1535 1536
  // Parser base's protected field members.

1537
  Scope* scope_;                   // Scope stack.
1538 1539
  // Stack of scopes for object literals we're currently parsing.
  Scope* object_literal_scope_ = nullptr;
1540
  Scope* original_scope_;  // The top scope for the current parsing item.
1541 1542
  FunctionState* function_state_;  // Function state stack.
  v8::Extension* extension_;
1543
  FuncNameInferrer fni_;
1544
  AstValueFactory* ast_value_factory_;  // Not owned.
1545
  typename Types::Factory ast_node_factory_;
1546
  RuntimeCallStats* runtime_call_stats_;
1547
  internal::Logger* logger_;
1548
  bool parsing_on_main_thread_;
1549
  uintptr_t stack_limit_;
1550
  PendingCompilationErrorHandler* pending_error_handler_;
1551

1552 1553
  // Parser base's private field members.

1554 1555
 private:
  Zone* zone_;
1556
  ExpressionScope* expression_scope_;
1557

1558
  std::vector<void*> pointer_buffer_;
1559
  std::vector<std::pair<VariableProxy*, int>> variable_buffer_;
1560

1561 1562
  Scanner* scanner_;

1563
  const UnoptimizedCompileFlags flags_;
1564 1565
  int function_literal_id_;

1566
  FunctionLiteral::EagerCompileHint default_eager_compile_hint_;
1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577

  // This struct is used to move information about the next arrow function from
  // the place where the arrow head was parsed to where the body will be parsed.
  // Nothing can be parsed between the head and the body, so it will be consumed
  // immediately after it's produced.
  // Preallocating the struct as part of the parser minimizes the cost of
  // supporting arrow functions on non-arrow expressions.
  struct NextArrowFunctionInfo {
    Scanner::Location strict_parameter_error_location =
        Scanner::Location::invalid();
    MessageTemplate strict_parameter_error_message = MessageTemplate::kNone;
1578
    DeclarationScope* scope = nullptr;
1579

1580
    bool HasInitialState() const { return scope == nullptr; }
1581

1582
    void Reset() {
1583
      scope = nullptr;
1584 1585 1586 1587
      ClearStrictParameterError();
      DCHECK(HasInitialState());
    }

1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599
    // Tracks strict-mode parameter violations of sloppy-mode arrow heads in
    // case the function ends up becoming strict mode. Only one global place to
    // track this is necessary since arrow functions with none-simple parameters
    // cannot become strict-mode later on.
    void ClearStrictParameterError() {
      strict_parameter_error_location = Scanner::Location::invalid();
      strict_parameter_error_message = MessageTemplate::kNone;
    }
  };

  FormalParametersT* parameters_;
  NextArrowFunctionInfo next_arrow_function_info_;
1600

1601 1602
  bool accept_IN_ = true;

1603
  bool allow_eval_cache_ = true;
1604 1605
};

1606 1607
template <typename Impl>
ParserBase<Impl>::FunctionState::FunctionState(
1608
    FunctionState** function_state_stack, Scope** scope_stack,
1609
    DeclarationScope* scope)
1610
    : BlockState(scope_stack, scope),
1611
      expected_property_count_(0),
1612
      suspend_count_(0),
1613 1614
      function_state_stack_(function_state_stack),
      outer_function_state_(*function_state_stack),
1615
      scope_(scope),
1616
      dont_optimize_reason_(BailoutReason::kNoReason),
1617
      next_function_is_likely_called_(false),
1618 1619
      previous_function_was_likely_called_(false),
      contains_function_or_eval_(false) {
1620
  *function_state_stack = this;
1621
  if (outer_function_state_) {
1622 1623
    outer_function_state_->previous_function_was_likely_called_ =
        outer_function_state_->next_function_is_likely_called_;
1624
    outer_function_state_->next_function_is_likely_called_ = false;
1625
  }
1626 1627
}

1628 1629
template <typename Impl>
ParserBase<Impl>::FunctionState::~FunctionState() {
1630 1631 1632
  *function_state_stack_ = outer_function_state_;
}

1633 1634
template <typename Impl>
void ParserBase<Impl>::ReportUnexpectedToken(Token::Value token) {
1635
  return impl()->ReportUnexpectedTokenAt(scanner_->location(), token);
1636 1637
}

1638 1639
template <typename Impl>
typename ParserBase<Impl>::IdentifierT
1640 1641
ParserBase<Impl>::ParseAndClassifyIdentifier(Token::Value next) {
  DCHECK_EQ(scanner()->current_token(), next);
1642
  if (V8_LIKELY(base::IsInRange(next, Token::IDENTIFIER, Token::ASYNC))) {
1643
    IdentifierT name = impl()->GetIdentifier();
1644 1645
    if (V8_UNLIKELY(impl()->IsArguments(name) &&
                    scope()->ShouldBanArguments())) {
1646 1647
      ReportMessage(
          MessageTemplate::kArgumentsDisallowedInInitializerAndStaticBlock);
1648
      return impl()->EmptyIdentifierString();
1649
    }
1650
    return name;
1651 1652
  }

1653
  if (!Token::IsValidIdentifier(next, language_mode(), is_generator(),
1654 1655
                                flags().is_module() || is_async_function() ||
                                    is_class_static_block())) {
1656 1657 1658 1659 1660
    ReportUnexpectedToken(next);
    return impl()->EmptyIdentifierString();
  }

  if (next == Token::AWAIT) {
1661
    expression_scope()->RecordAsyncArrowParametersError(
1662
        scanner()->location(), MessageTemplate::kAwaitBindingIdentifier);
1663
    return impl()->GetIdentifier();
1664
  }
1665 1666

  DCHECK(Token::IsStrictReservedWord(next));
1667
  expression_scope()->RecordStrictModeParameterError(
1668
      scanner()->location(), MessageTemplate::kUnexpectedStrictReserved);
1669
  return impl()->GetIdentifier();
1670 1671
}

1672
template <class Impl>
1673 1674
typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifier(
    FunctionKind function_kind) {
1675
  Token::Value next = Next();
1676 1677 1678

  if (!Token::IsValidIdentifier(
          next, language_mode(), IsGeneratorFunction(function_kind),
1679
          flags().is_module() || IsAsyncFunction(function_kind))) {
1680
    ReportUnexpectedToken(next);
1681
    return impl()->EmptyIdentifierString();
1682 1683
  }

1684
  return impl()->GetIdentifier();
1685 1686
}

1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700
template <typename Impl>
typename ParserBase<Impl>::IdentifierT
ParserBase<Impl>::ParseNonRestrictedIdentifier() {
  IdentifierT result = ParseIdentifier();

  if (is_strict(language_mode()) &&
      V8_UNLIKELY(impl()->IsEvalOrArguments(result))) {
    impl()->ReportMessageAt(scanner()->location(),
                            MessageTemplate::kStrictEvalArguments);
  }

  return result;
}

1701
template <typename Impl>
1702
typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParsePropertyName() {
1703
  Token::Value next = Next();
1704 1705 1706 1707
  if (V8_LIKELY(Token::IsPropertyName(next))) {
    if (peek() == Token::COLON) return impl()->GetSymbol();
    return impl()->GetIdentifier();
  }
1708

1709 1710
  ReportUnexpectedToken(next);
  return impl()->EmptyIdentifierString();
1711 1712
}

1713 1714
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
1715
ParserBase<Impl>::ParsePropertyOrPrivatePropertyName() {
1716 1717 1718
  int pos = position();
  IdentifierT name;
  ExpressionT key;
1719 1720 1721 1722
  Token::Value next = Next();
  if (V8_LIKELY(Token::IsPropertyName(next))) {
    name = impl()->GetSymbol();
    key = factory()->NewStringLiteral(name, pos);
1723
  } else if (next == Token::PRIVATE_NAME) {
1724 1725 1726 1727 1728 1729 1730
    // In the case of a top level function, we completely skip
    // analysing it's scope, meaning, we don't have a chance to
    // resolve private names and find that they are not enclosed in a
    // class body.
    //
    // Here, we check if this is a new private name reference in a top
    // level function and throw an error if so.
1731
    PrivateNameScopeIterator private_name_scope_iter(scope());
1732 1733
    // Parse the identifier so that we can display it in the error message
    name = impl()->GetIdentifier();
1734
    if (private_name_scope_iter.Done()) {
1735 1736
      impl()->ReportMessageAt(Scanner::Location(pos, pos + 1),
                              MessageTemplate::kInvalidPrivateFieldResolution,
1737
                              impl()->GetRawNameFromIdentifier(name));
1738
      return impl()->FailureExpression();
1739
    }
1740 1741
    key =
        impl()->ExpressionFromPrivateName(&private_name_scope_iter, name, pos);
1742
  } else {
1743 1744
    ReportUnexpectedToken(next);
    return impl()->FailureExpression();
1745 1746 1747 1748 1749
  }
  impl()->PushLiteralName(name);
  return key;
}

1750
template <typename Impl>
1751
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseRegExpLiteral() {
1752
  int pos = peek_position();
1753
  if (!scanner()->ScanRegExpPattern()) {
1754 1755
    Next();
    ReportMessage(MessageTemplate::kUnterminatedRegExp);
1756
    return impl()->FailureExpression();
1757 1758
  }

1759
  IdentifierT js_pattern = impl()->GetNextSymbol();
1760
  Maybe<int> flags = scanner()->ScanRegExpFlags();
1761 1762 1763
  if (flags.IsNothing()) {
    Next();
    ReportMessage(MessageTemplate::kMalformedRegExpFlags);
1764
    return impl()->FailureExpression();
1765 1766
  }
  Next();
1767
  return factory()->NewRegExpLiteral(js_pattern, flags.FromJust(), pos);
1768 1769
}

1770
template <typename Impl>
1771
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBindingPattern() {
1772 1773 1774 1775 1776 1777 1778 1779 1780 1781
  // Pattern ::
  //   Identifier
  //   ArrayLiteral
  //   ObjectLiteral

  int beg_pos = peek_position();
  Token::Value token = peek();
  ExpressionT result;

  if (Token::IsAnyIdentifier(token)) {
1782
    IdentifierT name = ParseAndClassifyIdentifier(Next());
1783 1784 1785 1786
    if (V8_UNLIKELY(is_strict(language_mode()) &&
                    impl()->IsEvalOrArguments(name))) {
      impl()->ReportMessageAt(scanner()->location(),
                              MessageTemplate::kStrictEvalArguments);
1787
      return impl()->FailureExpression();
1788
    }
1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800
    return impl()->ExpressionFromIdentifier(name, beg_pos);
  }

  CheckStackOverflow();

  if (token == Token::LBRACK) {
    result = ParseArrayLiteral();
  } else if (token == Token::LBRACE) {
    result = ParseObjectLiteral();
  } else {
    ReportUnexpectedToken(Next());
    return impl()->FailureExpression();
1801 1802 1803 1804 1805
  }

  return result;
}

1806
template <typename Impl>
1807 1808
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParsePrimaryExpression() {
1809 1810
  CheckStackOverflow();

1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825
  // PrimaryExpression ::
  //   'this'
  //   'null'
  //   'true'
  //   'false'
  //   Identifier
  //   Number
  //   String
  //   ArrayLiteral
  //   ObjectLiteral
  //   RegExpLiteral
  //   ClassLiteral
  //   '(' Expression ')'
  //   TemplateLiteral
  //   do Block
1826
  //   AsyncFunctionLiteral
1827 1828

  int beg_pos = peek_position();
1829
  Token::Value token = peek();
1830

1831
  if (Token::IsAnyIdentifier(token)) {
1832 1833
    Consume(token);

1834
    FunctionKind kind = FunctionKind::kArrowFunction;
1835

1836
    if (V8_UNLIKELY(token == Token::ASYNC &&
1837 1838
                    !scanner()->HasLineTerminatorBeforeNext() &&
                    !scanner()->literal_contains_escapes())) {
1839 1840
      // async function ...
      if (peek() == Token::FUNCTION) return ParseAsyncFunctionLiteral();
1841

1842 1843 1844 1845
      // async Identifier => ...
      if (peek_any_identifier() && PeekAhead() == Token::ARROW) {
        token = Next();
        beg_pos = position();
1846
        kind = FunctionKind::kAsyncArrowFunction;
1847 1848
      }
    }
1849

1850
    if (V8_UNLIKELY(peek() == Token::ARROW)) {
1851
      ArrowHeadParsingScope parsing_scope(impl(), kind);
1852
      IdentifierT name = ParseAndClassifyIdentifier(token);
1853
      ClassifyParameter(name, beg_pos, end_position());
1854 1855
      ExpressionT result =
          impl()->ExpressionFromIdentifier(name, beg_pos, InferName::kNo);
1856
      parsing_scope.SetInitializers(0, peek_position());
1857
      next_arrow_function_info_.scope = parsing_scope.ValidateAndCreateScope();
1858
      return result;
1859
    }
1860

1861 1862
    IdentifierT name = ParseAndClassifyIdentifier(token);
    return impl()->ExpressionFromIdentifier(name, beg_pos);
1863 1864 1865 1866 1867 1868
  }

  if (Token::IsLiteral(token)) {
    return impl()->ExpressionFromLiteral(Next(), beg_pos);
  }

1869
  switch (token) {
1870 1871 1872
    case Token::NEW:
      return ParseMemberWithPresentNewPrefixesExpression();

1873 1874
    case Token::THIS: {
      Consume(Token::THIS);
1875
      return impl()->NewThisExpression(beg_pos);
1876 1877 1878 1879
    }

    case Token::ASSIGN_DIV:
    case Token::DIV:
1880
      return ParseRegExpLiteral();
1881

1882 1883 1884 1885
    case Token::FUNCTION:
      return ParseFunctionExpression();

    case Token::SUPER: {
1886
      return ParseSuperExpression();
1887 1888 1889 1890
    }
    case Token::IMPORT:
      return ParseImportExpressions();

1891
    case Token::LBRACK:
1892
      return ParseArrayLiteral();
1893 1894

    case Token::LBRACE:
1895
      return ParseObjectLiteral();
1896 1897 1898 1899

    case Token::LPAREN: {
      Consume(Token::LPAREN);
      if (Check(Token::RPAREN)) {
1900
        // ()=>x.  The continuation that consumes the => is in
1901
        // ParseAssignmentExpressionCoverGrammar.
1902
        if (peek() != Token::ARROW) ReportUnexpectedToken(Token::RPAREN);
1903 1904
        next_arrow_function_info_.scope =
            NewFunctionScope(FunctionKind::kArrowFunction);
1905 1906
        return factory()->NewEmptyParentheses(beg_pos);
      }
1907
      Scope::Snapshot scope_snapshot(scope());
1908
      ArrowHeadParsingScope maybe_arrow(impl(), FunctionKind::kArrowFunction);
1909 1910
      // Heuristically try to detect immediately called functions before
      // seeing the call parentheses.
1911 1912
      if (peek() == Token::FUNCTION ||
          (peek() == Token::ASYNC && PeekAhead() == Token::FUNCTION)) {
1913 1914
        function_state_->set_next_function_is_likely_called();
      }
1915 1916
      AcceptINScope scope(this, true);
      ExpressionT expr = ParseExpressionCoverGrammar();
1917
      expr->mark_parenthesized();
1918
      Expect(Token::RPAREN);
1919 1920

      if (peek() == Token::ARROW) {
1921
        next_arrow_function_info_.scope = maybe_arrow.ValidateAndCreateScope();
1922
        scope_snapshot.Reparent(next_arrow_function_info_.scope);
1923 1924
      } else {
        maybe_arrow.ValidateExpression();
1925 1926
      }

1927 1928 1929 1930 1931
      return expr;
    }

    case Token::CLASS: {
      Consume(Token::CLASS);
1932
      int class_token_pos = position();
1933
      IdentifierT name = impl()->NullIdentifier();
1934 1935 1936
      bool is_strict_reserved_name = false;
      Scanner::Location class_name_location = Scanner::Location::invalid();
      if (peek_any_identifier()) {
1937
        name = ParseAndClassifyIdentifier(Next());
1938
        class_name_location = scanner()->location();
1939 1940
        is_strict_reserved_name =
            Token::IsStrictReservedWord(scanner()->current_token());
1941
      }
1942
      return ParseClassLiteral(name, class_name_location,
1943
                               is_strict_reserved_name, class_token_pos);
1944 1945 1946 1947
    }

    case Token::TEMPLATE_SPAN:
    case Token::TEMPLATE_TAIL:
1948
      return ParseTemplateLiteral(impl()->NullExpression(), beg_pos, false);
1949 1950

    case Token::MOD:
1951
      if (flags().allow_natives_syntax() || extension_ != nullptr) {
1952
        return ParseV8Intrinsic();
1953 1954 1955 1956 1957 1958 1959 1960
      }
      break;

    default:
      break;
  }

  ReportUnexpectedToken(Next());
1961
  return impl()->FailureExpression();
1962 1963
}

1964
template <typename Impl>
1965
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression() {
1966
  ExpressionParsingScope expression_scope(impl());
1967 1968
  AcceptINScope scope(this, true);
  ExpressionT result = ParseExpressionCoverGrammar();
1969 1970 1971 1972 1973 1974 1975 1976 1977 1978
  expression_scope.ValidateExpression();
  return result;
}

template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseAssignmentExpression() {
  ExpressionParsingScope expression_scope(impl());
  ExpressionT result = ParseAssignmentExpressionCoverGrammar();
  expression_scope.ValidateExpression();
1979 1980 1981
  return result;
}

1982
template <typename Impl>
1983
typename ParserBase<Impl>::ExpressionT
1984
ParserBase<Impl>::ParseExpressionCoverGrammar() {
1985 1986 1987 1988
  // Expression ::
  //   AssignmentExpression
  //   Expression ',' AssignmentExpression

1989
  ExpressionListT list(pointer_buffer());
1990
  ExpressionT expression;
1991
  AccumulationScope accumulation_scope(expression_scope());
1992
  int variable_index = 0;
1993
  while (true) {
1994
    if (V8_UNLIKELY(peek() == Token::ELLIPSIS)) {
1995 1996
      return ParseArrowParametersWithRest(&list, &accumulation_scope,
                                          variable_index);
1997
    }
1998

1999 2000 2001 2002
    int expr_pos = peek_position();
    expression = ParseAssignmentExpressionCoverGrammar();

    ClassifyArrowParameter(&accumulation_scope, expr_pos, expression);
2003
    list.Add(expression);
2004

2005 2006 2007
    variable_index =
        expression_scope()->SetInitializers(variable_index, peek_position());

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

2010
    if (peek() == Token::RPAREN && PeekAhead() == Token::ARROW) {
2011 2012
      // a trailing comma is allowed at the end of an arrow parameter list
      break;
2013
    }
2014 2015 2016 2017 2018 2019 2020

    // 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();
    }
2021 2022
  }

2023 2024 2025 2026
  // Return the single element if the list is empty. We need to do this because
  // callers of this function care about the type of the result if there was
  // only a single assignment expression. The preparser would lose this
  // information otherwise.
2027
  if (list.length() == 1) return expression;
2028
  return impl()->ExpressionListToExpression(list);
2029 2030
}

2031 2032
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
2033 2034
ParserBase<Impl>::ParseArrowParametersWithRest(
    typename ParserBase<Impl>::ExpressionListT* list,
2035
    AccumulationScope* accumulation_scope, int seen_variables) {
2036 2037 2038 2039 2040
  Consume(Token::ELLIPSIS);

  Scanner::Location ellipsis = scanner()->location();
  int pattern_pos = peek_position();
  ExpressionT pattern = ParseBindingPattern();
2041
  ClassifyArrowParameter(accumulation_scope, pattern_pos, pattern);
2042

2043
  expression_scope()->RecordNonSimpleParameter();
2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056

  if (V8_UNLIKELY(peek() == Token::ASSIGN)) {
    ReportMessage(MessageTemplate::kRestDefaultInitializer);
    return impl()->FailureExpression();
  }

  ExpressionT spread =
      factory()->NewSpread(pattern, ellipsis.beg_pos, pattern_pos);
  if (V8_UNLIKELY(peek() == Token::COMMA)) {
    ReportMessage(MessageTemplate::kParamAfterRest);
    return impl()->FailureExpression();
  }

2057 2058
  expression_scope()->SetInitializers(seen_variables, peek_position());

2059 2060 2061 2062
  // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only
  // as the formal parameters of'(x, y, ...z) => foo', and is not itself a
  // valid expression.
  if (peek() != Token::RPAREN || PeekAhead() != Token::ARROW) {
2063
    impl()->ReportUnexpectedTokenAt(ellipsis, Token::ELLIPSIS);
2064 2065 2066 2067 2068 2069 2070
    return impl()->FailureExpression();
  }

  list->Add(spread);
  return impl()->ExpressionListToExpression(*list);
}

2071
template <typename Impl>
2072
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseArrayLiteral() {
2073 2074 2075 2076
  // ArrayLiteral ::
  //   '[' Expression? (',' Expression?)* ']'

  int pos = peek_position();
2077
  ExpressionListT values(pointer_buffer());
2078
  int first_spread_index = -1;
2079
  Consume(Token::LBRACK);
2080 2081 2082

  AccumulationScope accumulation_scope(expression_scope());

2083
  while (!Check(Token::RBRACK)) {
2084
    ExpressionT elem;
2085
    if (peek() == Token::COMMA) {
2086
      elem = factory()->NewTheHoleLiteral();
2087 2088
    } else if (Check(Token::ELLIPSIS)) {
      int start_pos = position();
nikolaos's avatar
nikolaos committed
2089
      int expr_pos = peek_position();
2090
      AcceptINScope scope(this, true);
2091 2092
      ExpressionT argument =
          ParsePossibleDestructuringSubPattern(&accumulation_scope);
nikolaos's avatar
nikolaos committed
2093
      elem = factory()->NewSpread(argument, start_pos, expr_pos);
2094 2095

      if (first_spread_index < 0) {
2096
        first_spread_index = values.length();
2097 2098
      }

2099
      if (argument->IsAssignment()) {
2100
        expression_scope()->RecordPatternError(
2101
            Scanner::Location(start_pos, end_position()),
2102 2103
            MessageTemplate::kInvalidDestructuringTarget);
      }
2104 2105

      if (peek() == Token::COMMA) {
2106
        expression_scope()->RecordPatternError(
2107
            Scanner::Location(start_pos, end_position()),
2108 2109 2110
            MessageTemplate::kElementAfterRest);
      }
    } else {
2111
      AcceptINScope scope(this, true);
2112
      elem = ParsePossibleDestructuringSubPattern(&accumulation_scope);
2113
    }
2114
    values.Add(elem);
2115
    if (peek() != Token::RBRACK) {
2116
      Expect(Token::COMMA);
2117
      if (elem->IsFailureExpression()) return elem;
2118 2119 2120
    }
  }

2121
  return factory()->NewArrayLiteral(values, first_spread_index, pos);
2122 2123
}

2124
template <class Impl>
2125
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseProperty(
2126 2127 2128 2129
    ParsePropertyInfo* prop_info) {
  DCHECK_EQ(prop_info->kind, ParsePropertyKind::kNotSet);
  DCHECK_EQ(prop_info->function_flags, ParseFunctionFlag::kIsNormal);
  DCHECK(!prop_info->is_computed_name);
2130

2131 2132
  if (Check(Token::ASYNC)) {
    Token::Value token = peek();
2133
    if ((token != Token::MUL && prop_info->ParsePropertyKindFromToken(token)) ||
2134
        scanner()->HasLineTerminatorBeforeNext()) {
2135
      prop_info->name = impl()->GetIdentifier();
2136 2137
      impl()->PushLiteralName(prop_info->name);
      return factory()->NewStringLiteral(prop_info->name, position());
2138
    }
2139 2140 2141
    if (V8_UNLIKELY(scanner()->literal_contains_escapes())) {
      impl()->ReportUnexpectedToken(Token::ESCAPED_KEYWORD);
    }
2142 2143
    prop_info->function_flags = ParseFunctionFlag::kIsAsync;
    prop_info->kind = ParsePropertyKind::kMethod;
2144 2145
  }

2146
  if (Check(Token::MUL)) {
2147 2148
    prop_info->function_flags |= ParseFunctionFlag::kIsGenerator;
    prop_info->kind = ParsePropertyKind::kMethod;
2149 2150
  }

2151
  if (prop_info->kind == ParsePropertyKind::kNotSet &&
2152
      base::IsInRange(peek(), Token::GET, Token::SET)) {
2153 2154
    Token::Value token = Next();
    if (prop_info->ParsePropertyKindFromToken(peek())) {
2155
      prop_info->name = impl()->GetIdentifier();
2156 2157
      impl()->PushLiteralName(prop_info->name);
      return factory()->NewStringLiteral(prop_info->name, position());
2158
    }
2159 2160 2161 2162 2163 2164 2165 2166
    if (V8_UNLIKELY(scanner()->literal_contains_escapes())) {
      impl()->ReportUnexpectedToken(Token::ESCAPED_KEYWORD);
    }
    if (token == Token::GET) {
      prop_info->kind = ParsePropertyKind::kAccessorGetter;
    } else if (token == Token::SET) {
      prop_info->kind = ParsePropertyKind::kAccessorSetter;
    }
2167 2168
  }

2169 2170
  int pos = peek_position();

2171 2172 2173 2174 2175 2176 2177 2178 2179
  // 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.
2180 2181 2182
  bool is_array_index;
  uint32_t index;
  switch (peek()) {
2183
    case Token::PRIVATE_NAME:
2184
      prop_info->is_private = true;
2185 2186
      is_array_index = false;
      Consume(Token::PRIVATE_NAME);
2187 2188
      if (prop_info->kind == ParsePropertyKind::kNotSet) {
        prop_info->ParsePropertyKindFromToken(peek());
2189
      }
2190
      prop_info->name = impl()->GetIdentifier();
2191 2192 2193 2194 2195 2196
      if (V8_UNLIKELY(prop_info->position ==
                      PropertyPosition::kObjectLiteral)) {
        ReportUnexpectedToken(Token::PRIVATE_NAME);
        prop_info->kind = ParsePropertyKind::kNotSet;
        return impl()->FailureExpression();
      }
2197 2198
      break;

2199 2200
    case Token::STRING:
      Consume(Token::STRING);
2201 2202
      prop_info->name = peek() == Token::COLON ? impl()->GetSymbol()
                                               : impl()->GetIdentifier();
2203
      is_array_index = impl()->IsArrayIndex(prop_info->name, &index);
2204 2205 2206 2207
      break;

    case Token::SMI:
      Consume(Token::SMI);
2208 2209 2210
      index = scanner()->smi_value();
      is_array_index = true;
      // Token::SMI were scanned from their canonical representation.
2211
      prop_info->name = impl()->GetSymbol();
2212 2213
      break;

2214
    case Token::NUMBER: {
2215
      Consume(Token::NUMBER);
2216 2217
      prop_info->name = impl()->GetNumberAsSymbol();
      is_array_index = impl()->IsArrayIndex(prop_info->name, &index);
2218
      break;
2219
    }
2220 2221 2222

    case Token::BIGINT: {
      Consume(Token::BIGINT);
2223
      prop_info->name = impl()->GetSymbol();
2224 2225 2226 2227
      is_array_index = impl()->IsArrayIndex(prop_info->name, &index);
      break;
    }

2228
    case Token::LBRACK: {
2229 2230
      prop_info->name = impl()->NullIdentifier();
      prop_info->is_computed_name = true;
2231
      Consume(Token::LBRACK);
2232 2233
      AcceptINScope scope(this, true);
      ExpressionT expression = ParseAssignmentExpression();
2234
      Expect(Token::RBRACK);
2235 2236
      if (prop_info->kind == ParsePropertyKind::kNotSet) {
        prop_info->ParsePropertyKindFromToken(peek());
2237 2238
      }
      return expression;
2239 2240
    }

2241
    case Token::ELLIPSIS:
2242 2243
      if (prop_info->kind == ParsePropertyKind::kNotSet) {
        prop_info->name = impl()->NullIdentifier();
2244
        Consume(Token::ELLIPSIS);
2245
        AcceptINScope scope(this, true);
2246 2247 2248
        int start_pos = peek_position();
        ExpressionT expression =
            ParsePossibleDestructuringSubPattern(prop_info->accumulation_scope);
2249
        prop_info->kind = ParsePropertyKind::kSpread;
2250

2251
        if (!IsValidReferenceExpression(expression)) {
2252 2253
          expression_scope()->RecordDeclarationError(
              Scanner::Location(start_pos, end_position()),
2254
              MessageTemplate::kInvalidRestBindingPattern);
2255 2256
          expression_scope()->RecordPatternError(
              Scanner::Location(start_pos, end_position()),
2257
              MessageTemplate::kInvalidRestAssignmentPattern);
2258 2259 2260
        }

        if (peek() != Token::RBRACE) {
2261 2262
          expression_scope()->RecordPatternError(
              scanner()->location(), MessageTemplate::kElementAfterRest);
2263
        }
2264 2265
        return expression;
      }
2266
      V8_FALLTHROUGH;
2267

2268
    default:
2269
      prop_info->name = ParsePropertyName();
2270
      is_array_index = false;
2271 2272 2273
      break;
  }

2274 2275
  if (prop_info->kind == ParsePropertyKind::kNotSet) {
    prop_info->ParsePropertyKindFromToken(peek());
2276
  }
2277
  impl()->PushLiteralName(prop_info->name);
2278
  return is_array_index ? factory()->NewNumberLiteral(index, pos)
2279
                        : factory()->NewStringLiteral(prop_info->name, pos);
2280 2281
}

2282
template <typename Impl>
2283
typename ParserBase<Impl>::ClassLiteralPropertyT
2284 2285 2286
ParserBase<Impl>::ParseClassPropertyDefinition(ClassInfo* class_info,
                                               ParsePropertyInfo* prop_info,
                                               bool has_extends) {
2287
  DCHECK_NOT_NULL(class_info);
2288
  DCHECK_EQ(prop_info->position, PropertyPosition::kClassLiteral);
2289

2290
  Token::Value name_token = peek();
2291 2292
  int property_beg_pos = scanner()->peek_location().beg_pos;
  int name_token_position = property_beg_pos;
2293 2294 2295
  ExpressionT name_expression;
  if (name_token == Token::STATIC) {
    Consume(Token::STATIC);
2296
    name_token_position = scanner()->peek_location().beg_pos;
2297
    if (peek() == Token::LPAREN) {
2298 2299
      prop_info->kind = ParsePropertyKind::kMethod;
      // TODO(bakkot) specialize on 'static'
2300
      prop_info->name = impl()->GetIdentifier();
2301 2302
      name_expression =
          factory()->NewStringLiteral(prop_info->name, position());
2303 2304
    } else if (peek() == Token::ASSIGN || peek() == Token::SEMICOLON ||
               peek() == Token::RBRACE) {
2305
      // TODO(bakkot) specialize on 'static'
2306
      prop_info->name = impl()->GetIdentifier();
2307 2308
      name_expression =
          factory()->NewStringLiteral(prop_info->name, position());
2309
    } else {
2310
      prop_info->is_static = true;
2311
      name_expression = ParseProperty(prop_info);
2312
    }
2313
  } else {
2314
    name_expression = ParseProperty(prop_info);
2315 2316
  }

2317 2318
  if (!class_info->has_name_static_property && prop_info->is_static &&
      impl()->IsName(prop_info->name)) {
2319
    class_info->has_name_static_property = true;
2320 2321
  }

2322
  switch (prop_info->kind) {
2323
    case ParsePropertyKind::kAssign:
2324
    case ParsePropertyKind::kClassField:
2325
    case ParsePropertyKind::kShorthandOrClassField:
2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336
    case ParsePropertyKind::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.
      prop_info->kind = ParsePropertyKind::kClassField;
      DCHECK_IMPLIES(prop_info->is_computed_name, !prop_info->is_private);
2337

2338 2339 2340
      if (!prop_info->is_computed_name) {
        CheckClassFieldName(prop_info->name, prop_info->is_static);
      }
2341

2342 2343 2344
      ExpressionT initializer = ParseMemberInitializer(
          class_info, property_beg_pos, prop_info->is_static);
      ExpectSemicolon();
2345

2346 2347 2348 2349 2350
      ClassLiteralPropertyT result = factory()->NewClassLiteralProperty(
          name_expression, initializer, ClassLiteralProperty::FIELD,
          prop_info->is_static, prop_info->is_computed_name,
          prop_info->is_private);
      impl()->SetFunctionNameFromPropertyName(result, prop_info->name);
2351

2352 2353
      return result;
    }
2354
    case ParsePropertyKind::kMethod: {
2355 2356 2357
      // MethodDefinition
      //    PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
      //    '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2358 2359 2360 2361
      //    async PropertyName '(' StrictFormalParameters ')'
      //        '{' FunctionBody '}'
      //    async '*' PropertyName '(' StrictFormalParameters ')'
      //        '{' FunctionBody '}'
2362

2363 2364 2365 2366
      if (!prop_info->is_computed_name) {
        CheckClassMethodName(prop_info->name, ParsePropertyKind::kMethod,
                             prop_info->function_flags, prop_info->is_static,
                             &class_info->has_seen_constructor);
2367 2368
      }

2369 2370
      FunctionKind kind =
          MethodKindFor(prop_info->is_static, prop_info->function_flags);
2371

2372
      if (!prop_info->is_static && impl()->IsConstructor(prop_info->name)) {
2373
        class_info->has_seen_constructor = true;
2374
        kind = has_extends ? FunctionKind::kDerivedConstructor
2375 2376 2377 2378
                           : FunctionKind::kBaseConstructor;
      }

      ExpressionT value = impl()->ParseFunctionLiteral(
2379
          prop_info->name, scanner()->location(), kSkipFunctionNameCheck, kind,
2380
          name_token_position, FunctionSyntaxKind::kAccessorOrMethod,
2381
          language_mode(), nullptr);
2382

2383
      ClassLiteralPropertyT result = factory()->NewClassLiteralProperty(
2384 2385 2386 2387
          name_expression, value, ClassLiteralProperty::METHOD,
          prop_info->is_static, prop_info->is_computed_name,
          prop_info->is_private);
      impl()->SetFunctionNameFromPropertyName(result, prop_info->name);
2388
      return result;
2389 2390
    }

2391 2392
    case ParsePropertyKind::kAccessorGetter:
    case ParsePropertyKind::kAccessorSetter: {
2393 2394
      DCHECK_EQ(prop_info->function_flags, ParseFunctionFlag::kIsNormal);
      bool is_get = prop_info->kind == ParsePropertyKind::kAccessorGetter;
2395

2396 2397 2398 2399
      if (!prop_info->is_computed_name) {
        CheckClassMethodName(prop_info->name, prop_info->kind,
                             ParseFunctionFlag::kIsNormal, prop_info->is_static,
                             &class_info->has_seen_constructor);
2400 2401 2402
        // 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.
2403 2404
        name_expression = factory()->NewStringLiteral(
            prop_info->name, name_expression->position());
2405 2406
      }

2407 2408 2409 2410 2411 2412 2413 2414
      FunctionKind kind;
      if (prop_info->is_static) {
        kind = is_get ? FunctionKind::kStaticGetterFunction
                      : FunctionKind::kStaticSetterFunction;
      } else {
        kind = is_get ? FunctionKind::kGetterFunction
                      : FunctionKind::kSetterFunction;
      }
2415

2416
      FunctionLiteralT value = impl()->ParseFunctionLiteral(
2417
          prop_info->name, scanner()->location(), kSkipFunctionNameCheck, kind,
2418
          name_token_position, FunctionSyntaxKind::kAccessorOrMethod,
2419
          language_mode(), nullptr);
2420

2421
      ClassLiteralProperty::Kind property_kind =
2422
          is_get ? ClassLiteralProperty::GETTER : ClassLiteralProperty::SETTER;
2423
      ClassLiteralPropertyT result = factory()->NewClassLiteralProperty(
2424 2425
          name_expression, value, property_kind, prop_info->is_static,
          prop_info->is_computed_name, prop_info->is_private);
2426 2427 2428
      const AstRawString* prefix =
          is_get ? ast_value_factory()->get_space_string()
                 : ast_value_factory()->set_space_string();
2429
      impl()->SetFunctionNameFromPropertyName(result, prop_info->name, prefix);
2430
      return result;
2431
    }
2432 2433
    case ParsePropertyKind::kValue:
    case ParsePropertyKind::kShorthand:
2434
    case ParsePropertyKind::kSpread:
2435
      impl()->ReportUnexpectedTokenAt(
2436 2437
          Scanner::Location(name_token_position, name_expression->position()),
          name_token);
2438
      return impl()->NullLiteralProperty();
2439 2440 2441 2442
  }
  UNREACHABLE();
}

2443
template <typename Impl>
2444 2445
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseMemberInitializer(
    ClassInfo* class_info, int beg_pos, bool is_static) {
2446
  FunctionParsingScope body_parsing_scope(impl());
2447
  DeclarationScope* initializer_scope =
2448
      is_static ? class_info->static_elements_scope
2449
                : class_info->instance_members_scope;
2450
  FunctionKind function_kind =
2451
      is_static ? FunctionKind::kClassStaticInitializerFunction
2452
                : FunctionKind::kClassMembersInitializerFunction;
2453 2454

  if (initializer_scope == nullptr) {
2455
    initializer_scope = NewFunctionScope(function_kind);
2456
    // TODO(gsathya): Make scopes be non contiguous.
2457
    initializer_scope->set_start_position(beg_pos);
2458 2459 2460 2461 2462 2463 2464 2465
    initializer_scope->SetLanguageMode(LanguageMode::kStrict);
  }

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

2466 2467
    AcceptINScope scope(this, true);
    initializer = ParseAssignmentExpression();
2468
  } else {
2469
    initializer = factory()->NewUndefinedLiteral(kNoSourcePosition);
2470
  }
2471

2472
  initializer_scope->set_end_position(end_position());
2473
  if (is_static) {
2474 2475
    class_info->static_elements_scope = initializer_scope;
    class_info->has_static_elements = true;
2476
  } else {
2477 2478
    class_info->instance_members_scope = initializer_scope;
    class_info->has_instance_members = true;
2479 2480 2481
  }

  return initializer;
2482 2483
}

2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509
template <typename Impl>
typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseClassStaticBlock(
    ClassInfo* class_info) {
  Consume(Token::STATIC);

  DeclarationScope* initializer_scope = class_info->static_elements_scope;
  if (initializer_scope == nullptr) {
    initializer_scope =
        NewFunctionScope(FunctionKind::kClassStaticInitializerFunction);
    initializer_scope->set_start_position(position());
    initializer_scope->SetLanguageMode(LanguageMode::kStrict);
    class_info->static_elements_scope = initializer_scope;
  }

  FunctionState initializer_state(&function_state_, &scope_, initializer_scope);
  AcceptINScope accept_in(this, true);

  // Each static block has its own var and lexical scope, so make a new var
  // block scope instead of using the synthetic members initializer function
  // scope.
  BlockT static_block = ParseBlock(nullptr, NewVarblockScope());
  initializer_scope->set_end_position(end_position());
  class_info->has_static_elements = true;
  return static_block;
}

2510 2511
template <typename Impl>
typename ParserBase<Impl>::ObjectLiteralPropertyT
2512 2513 2514
ParserBase<Impl>::ParseObjectPropertyDefinition(ParsePropertyInfo* prop_info,
                                                bool* has_seen_proto) {
  DCHECK_EQ(prop_info->position, PropertyPosition::kObjectLiteral);
2515
  Token::Value name_token = peek();
2516
  Scanner::Location next_loc = scanner()->peek_location();
2517

2518
  ExpressionT name_expression = ParseProperty(prop_info);
2519 2520 2521

  DCHECK_IMPLIES(name_token == Token::PRIVATE_NAME, has_error());

2522 2523 2524
  IdentifierT name = prop_info->name;
  ParseFunctionFlags function_flags = prop_info->function_flags;
  ParsePropertyKind kind = prop_info->kind;
2525

2526
  switch (prop_info->kind) {
2527
    case ParsePropertyKind::kSpread:
2528
      DCHECK_EQ(function_flags, ParseFunctionFlag::kIsNormal);
2529
      DCHECK(!prop_info->is_computed_name);
2530
      DCHECK_EQ(Token::ELLIPSIS, name_token);
2531

2532 2533
      prop_info->is_computed_name = true;
      prop_info->is_rest = true;
2534 2535

      return factory()->NewObjectLiteralProperty(
2536
          factory()->NewTheHoleLiteral(), name_expression,
2537 2538
          ObjectLiteralProperty::SPREAD, true);

2539
    case ParsePropertyKind::kValue: {
2540
      DCHECK_EQ(function_flags, ParseFunctionFlag::kIsNormal);
2541

2542
      if (!prop_info->is_computed_name &&
2543
          scanner()->CurrentLiteralEquals("__proto__")) {
2544
        if (*has_seen_proto) {
2545 2546
          expression_scope()->RecordExpressionError(
              scanner()->location(), MessageTemplate::kDuplicateProto);
2547 2548
        }
        *has_seen_proto = true;
2549 2550
      }
      Consume(Token::COLON);
2551
      AcceptINScope scope(this, true);
2552 2553
      ExpressionT value =
          ParsePossibleDestructuringSubPattern(prop_info->accumulation_scope);
2554

2555
      ObjectLiteralPropertyT result = factory()->NewObjectLiteralProperty(
2556
          name_expression, value, prop_info->is_computed_name);
2557
      impl()->SetFunctionNameFromPropertyName(result, name);
2558
      return result;
2559 2560
    }

2561 2562
    case ParsePropertyKind::kAssign:
    case ParsePropertyKind::kShorthandOrClassField:
2563
    case ParsePropertyKind::kShorthand: {
2564 2565 2566 2567 2568 2569
      // PropertyDefinition
      //    IdentifierReference
      //    CoverInitializedName
      //
      // CoverInitializedName
      //    IdentifierReference Initializer?
2570
      DCHECK_EQ(function_flags, ParseFunctionFlag::kIsNormal);
2571

2572 2573 2574
      if (!Token::IsValidIdentifier(
              name_token, language_mode(), is_generator(),
              flags().is_module() || is_async_function())) {
2575
        ReportUnexpectedToken(Next());
2576
        return impl()->NullLiteralProperty();
2577 2578
      }

2579
      DCHECK(!prop_info->is_computed_name);
2580

2581 2582
      if (name_token == Token::AWAIT) {
        DCHECK(!is_async_function());
2583
        expression_scope()->RecordAsyncArrowParametersError(
2584 2585 2586 2587 2588
            next_loc, MessageTemplate::kAwaitBindingIdentifier);
      }
      ExpressionT lhs =
          impl()->ExpressionFromIdentifier(name, next_loc.beg_pos);
      if (!IsAssignableIdentifier(lhs)) {
2589 2590
        expression_scope()->RecordPatternError(
            next_loc, MessageTemplate::kStrictEvalArguments);
2591
      }
2592

2593
      ExpressionT value;
2594 2595
      if (peek() == Token::ASSIGN) {
        Consume(Token::ASSIGN);
2596 2597 2598 2599 2600 2601 2602 2603
        {
          AcceptINScope scope(this, true);
          ExpressionT rhs = ParseAssignmentExpression();
          value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs,
                                           kNoSourcePosition);
          impl()->SetFunctionNameFromIdentifierRef(rhs, lhs);
        }
        expression_scope()->RecordExpressionError(
2604
            Scanner::Location(next_loc.beg_pos, end_position()),
2605 2606 2607 2608 2609
            MessageTemplate::kInvalidCoverInitializedName);
      } else {
        value = lhs;
      }

2610
      ObjectLiteralPropertyT result = factory()->NewObjectLiteralProperty(
2611
          name_expression, value, ObjectLiteralProperty::COMPUTED, false);
2612 2613
      impl()->SetFunctionNameFromPropertyName(result, name);
      return result;
2614 2615
    }

2616
    case ParsePropertyKind::kMethod: {
2617 2618 2619
      // MethodDefinition
      //    PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
      //    '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2620

2621
      expression_scope()->RecordPatternError(
2622
          Scanner::Location(next_loc.beg_pos, end_position()),
2623
          MessageTemplate::kInvalidDestructuringTarget);
2624

2625 2626 2627 2628 2629 2630 2631
      std::unique_ptr<BlockState> block_state;
      if (object_literal_scope_ != nullptr) {
        DCHECK_EQ(object_literal_scope_->outer_scope(), scope_);
        block_state.reset(new BlockState(&scope_, object_literal_scope_));
      }
      constexpr bool kIsStatic = false;
      FunctionKind kind = MethodKindFor(kIsStatic, function_flags);
2632

2633
      ExpressionT value = impl()->ParseFunctionLiteral(
2634
          name, scanner()->location(), kSkipFunctionNameCheck, kind,
2635 2636
          next_loc.beg_pos, FunctionSyntaxKind::kAccessorOrMethod,
          language_mode(), nullptr);
2637

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

2645 2646
    case ParsePropertyKind::kAccessorGetter:
    case ParsePropertyKind::kAccessorSetter: {
2647
      DCHECK_EQ(function_flags, ParseFunctionFlag::kIsNormal);
2648
      bool is_get = kind == ParsePropertyKind::kAccessorGetter;
2649

2650
      expression_scope()->RecordPatternError(
2651
          Scanner::Location(next_loc.beg_pos, end_position()),
2652 2653
          MessageTemplate::kInvalidDestructuringTarget);

2654
      if (!prop_info->is_computed_name) {
2655 2656 2657
        // 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.
2658
        name_expression =
2659
            factory()->NewStringLiteral(name, name_expression->position());
2660
      }
2661

2662 2663 2664 2665 2666 2667
      std::unique_ptr<BlockState> block_state;
      if (object_literal_scope_ != nullptr) {
        DCHECK_EQ(object_literal_scope_->outer_scope(), scope_);
        block_state.reset(new BlockState(&scope_, object_literal_scope_));
      }

2668 2669 2670
      FunctionKind kind = is_get ? FunctionKind::kGetterFunction
                                 : FunctionKind::kSetterFunction;

2671 2672
      FunctionLiteralT value = impl()->ParseFunctionLiteral(
          name, scanner()->location(), kSkipFunctionNameCheck, kind,
2673 2674
          next_loc.beg_pos, FunctionSyntaxKind::kAccessorOrMethod,
          language_mode(), nullptr);
2675

2676 2677 2678 2679
      ObjectLiteralPropertyT result = factory()->NewObjectLiteralProperty(
          name_expression, value,
          is_get ? ObjectLiteralProperty::GETTER
                 : ObjectLiteralProperty::SETTER,
2680
          prop_info->is_computed_name);
2681 2682 2683 2684 2685
      const AstRawString* prefix =
          is_get ? ast_value_factory()->get_space_string()
                 : ast_value_factory()->set_space_string();
      impl()->SetFunctionNameFromPropertyName(result, name, prefix);
      return result;
2686
    }
2687

2688 2689
    case ParsePropertyKind::kClassField:
    case ParsePropertyKind::kNotSet:
2690
      ReportUnexpectedToken(Next());
2691
      return impl()->NullLiteralProperty();
2692
  }
2693
  UNREACHABLE();
2694 2695
}

2696
template <typename Impl>
2697
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral() {
2698 2699 2700 2701
  // ObjectLiteral ::
  // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}'

  int pos = peek_position();
2702
  ObjectPropertyListT properties(pointer_buffer());
2703
  int number_of_boilerplate_properties = 0;
2704

2705
  bool has_computed_names = false;
2706
  bool has_rest_property = false;
2707
  bool has_seen_proto = false;
2708

2709
  Consume(Token::LBRACE);
2710
  AccumulationScope accumulation_scope(expression_scope());
2711

2712 2713 2714 2715 2716
  // If methods appear inside the object literal, we'll enter this scope.
  Scope* block_scope = NewBlockScopeForObjectLiteral();
  block_scope->set_start_position(pos);
  BlockState object_literal_scope_state(&object_literal_scope_, block_scope);

2717
  while (!Check(Token::RBRACE)) {
2718
    FuncNameInferrerState fni_state(&fni_);
2719

2720
    ParsePropertyInfo prop_info(this, &accumulation_scope);
2721 2722 2723
    prop_info.position = PropertyPosition::kObjectLiteral;
    ObjectLiteralPropertyT property =
        ParseObjectPropertyDefinition(&prop_info, &has_seen_proto);
2724
    if (impl()->IsNull(property)) return impl()->FailureExpression();
2725

2726
    if (prop_info.is_computed_name) {
2727 2728 2729
      has_computed_names = true;
    }

2730
    if (prop_info.is_rest) {
2731 2732 2733
      has_rest_property = true;
    }

2734
    if (impl()->IsBoilerplateProperty(property) && !has_computed_names) {
2735 2736
      // Count CONSTANT or COMPUTED properties to maintain the enumeration
      // order.
2737 2738
      number_of_boilerplate_properties++;
    }
2739

2740
    properties.Add(property);
2741 2742

    if (peek() != Token::RBRACE) {
2743
      Expect(Token::COMMA);
2744 2745
    }

2746
    fni_.Infer();
2747 2748
  }

2749 2750 2751 2752 2753 2754 2755 2756 2757
  Variable* home_object = nullptr;
  if (block_scope->needs_home_object()) {
    home_object = block_scope->DeclareHomeObjectVariable(ast_value_factory());
    block_scope->set_end_position(end_position());
  } else {
    block_scope = block_scope->FinalizeBlockScope();
    DCHECK_NULL(block_scope);
  }

2758 2759 2760 2761 2762
  // 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.
2763
  if (has_rest_property && properties.length() > Code::kMaxArguments) {
2764
    expression_scope()->RecordPatternError(Scanner::Location(pos, position()),
2765 2766 2767
                                           MessageTemplate::kTooManyArguments);
  }

2768 2769 2770
  return impl()->InitializeObjectLiteral(
      factory()->NewObjectLiteral(properties, number_of_boilerplate_properties,
                                  pos, has_rest_property, home_object));
2771 2772
}

2773
template <typename Impl>
2774
void ParserBase<Impl>::ParseArguments(
2775
    typename ParserBase<Impl>::ExpressionListT* args, bool* has_spread,
2776
    ParsingArrowHeadFlag maybe_arrow) {
2777 2778 2779
  // Arguments ::
  //   '(' (AssignmentExpression)*[','] ')'

2780
  *has_spread = false;
2781
  Consume(Token::LPAREN);
2782
  AccumulationScope accumulation_scope(expression_scope());
2783

2784
  int variable_index = 0;
2785
  while (peek() != Token::RPAREN) {
2786 2787
    int start_pos = peek_position();
    bool is_spread = Check(Token::ELLIPSIS);
nikolaos's avatar
nikolaos committed
2788
    int expr_pos = peek_position();
2789

2790
    AcceptINScope scope(this, true);
2791
    ExpressionT argument = ParseAssignmentExpressionCoverGrammar();
2792

2793 2794
    if (V8_UNLIKELY(maybe_arrow == kMaybeArrowHead)) {
      ClassifyArrowParameter(&accumulation_scope, expr_pos, argument);
2795
      if (is_spread) {
2796
        expression_scope()->RecordNonSimpleParameter();
2797
        if (argument->IsAssignment()) {
2798
          expression_scope()->RecordAsyncArrowParametersError(
2799 2800 2801
              scanner()->location(), MessageTemplate::kRestDefaultInitializer);
        }
        if (peek() == Token::COMMA) {
2802
          expression_scope()->RecordAsyncArrowParametersError(
2803 2804 2805
              scanner()->peek_location(), MessageTemplate::kParamAfterRest);
        }
      }
2806
    }
2807
    if (is_spread) {
2808
      *has_spread = true;
nikolaos's avatar
nikolaos committed
2809
      argument = factory()->NewSpread(argument, start_pos, expr_pos);
2810
    }
2811
    args->Add(argument);
2812 2813 2814 2815

    variable_index =
        expression_scope()->SetInitializers(variable_index, peek_position());

2816
    if (!Check(Token::COMMA)) break;
2817
  }
2818

2819
  if (args->length() > Code::kMaxArguments) {
2820
    ReportMessage(MessageTemplate::kTooManyArguments);
2821
    return;
2822 2823
  }

2824
  Scanner::Location location = scanner_->location();
2825
  if (!Check(Token::RPAREN)) {
2826
    impl()->ReportMessageAt(location, MessageTemplate::kUnterminatedArgList);
2827 2828 2829 2830
  }
}

// Precedence = 2
2831 2832
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
2833
ParserBase<Impl>::ParseAssignmentExpressionCoverGrammar() {
2834 2835 2836 2837 2838 2839 2840 2841
  // AssignmentExpression ::
  //   ConditionalExpression
  //   ArrowFunction
  //   YieldExpression
  //   LeftHandSideExpression AssignmentOperator AssignmentExpression
  int lhs_beg_pos = peek_position();

  if (peek() == Token::YIELD && is_generator()) {
2842
    return ParseYieldExpression();
2843 2844
  }

2845
  FuncNameInferrerState fni_state(&fni_);
2846

2847 2848
  DCHECK_IMPLIES(!has_error(), next_arrow_function_info_.HasInitialState());

2849
  ExpressionT expression = ParseConditionalExpression();
2850

2851 2852
  Token::Value op = peek();

2853
  if (!Token::IsArrowOrAssignmentOp(op)) return expression;
2854 2855 2856

  // Arrow functions.
  if (V8_UNLIKELY(op == Token::ARROW)) {
2857
    Scanner::Location loc(lhs_beg_pos, end_position());
2858 2859 2860 2861 2862 2863 2864

    if (!impl()->IsIdentifier(expression) && !expression->is_parenthesized()) {
      impl()->ReportMessageAt(
          Scanner::Location(expression->position(), position()),
          MessageTemplate::kMalformedArrowFunParamList);
      return impl()->FailureExpression();
    }
2865

2866 2867
    DeclarationScope* scope = next_arrow_function_info_.scope;
    scope->set_start_position(lhs_beg_pos);
2868

2869
    FormalParametersT parameters(scope);
2870 2871 2872
    parameters.set_strict_parameter_error(
        next_arrow_function_info_.strict_parameter_error_location,
        next_arrow_function_info_.strict_parameter_error_message);
2873
    parameters.is_simple = scope->has_simple_parameters();
2874
    next_arrow_function_info_.Reset();
2875

2876
    impl()->DeclareArrowFunctionFormalParameters(&parameters, expression, loc);
2877

2878
    expression = ParseArrowFunctionLiteral(parameters);
2879

2880 2881 2882
    return expression;
  }

2883
  if (V8_LIKELY(impl()->IsAssignableIdentifier(expression))) {
2884 2885 2886 2887 2888
    if (expression->is_parenthesized()) {
      expression_scope()->RecordDeclarationError(
          Scanner::Location(lhs_beg_pos, end_position()),
          MessageTemplate::kInvalidDestructuringTarget);
    }
2889
    expression_scope()->MarkIdentifierAsAssigned();
2890 2891 2892 2893
  } else if (expression->IsProperty()) {
    expression_scope()->RecordDeclarationError(
        Scanner::Location(lhs_beg_pos, end_position()),
        MessageTemplate::kInvalidPropertyBindingPattern);
2894
    expression_scope()->ValidateAsExpression();
2895 2896
  } else if (expression->IsPattern() && op == Token::ASSIGN) {
    // Destructuring assignmment.
2897
    if (expression->is_parenthesized()) {
2898 2899 2900 2901 2902
      Scanner::Location loc(lhs_beg_pos, end_position());
      if (expression_scope()->IsCertainlyDeclaration()) {
        impl()->ReportMessageAt(loc,
                                MessageTemplate::kInvalidDestructuringTarget);
      } else {
2903
        // Syntax Error if LHS is neither object literal nor an array literal
2904 2905 2906
        // (Parenthesized literals are
        // CoverParenthesizedExpressionAndArrowParameterList).
        // #sec-assignment-operators-static-semantics-early-errors
2907
        impl()->ReportMessageAt(loc, MessageTemplate::kInvalidLhsInAssignment);
2908
      }
2909
    }
2910 2911
    expression_scope()->ValidateAsPattern(expression, lhs_beg_pos,
                                          end_position());
2912
  } else {
2913
    DCHECK(!IsValidReferenceExpression(expression));
2914 2915 2916
    // For web compatibility reasons, throw early errors only for logical
    // assignment, not for regular assignment.
    const bool early_error = Token::IsLogicalAssignmentOp(op);
2917 2918
    expression = RewriteInvalidReferenceExpression(
        expression, lhs_beg_pos, end_position(),
2919
        MessageTemplate::kInvalidLhsInAssignment, early_error);
2920
  }
2921

2922
  Consume(op);
2923
  int op_position = position();
2924

2925
  ExpressionT right = ParseAssignmentExpression();
2926

2927 2928
  // Anonymous function name inference applies to =, ||=, &&=, and ??=.
  if (op == Token::ASSIGN || Token::IsLogicalAssignmentOp(op)) {
2929 2930 2931 2932 2933 2934 2935 2936 2937 2938
    impl()->CheckAssigningFunctionLiteralToProperty(expression, right);

    // Check if the right hand side is a call to avoid inferring a
    // name if we're dealing with "a = function(){...}();"-like
    // expression.
    if (right->IsCall() || right->IsCallNew()) {
      fni_.RemoveLastFunction();
    } else {
      fni_.Infer();
    }
2939

2940
    impl()->SetFunctionNameFromIdentifierRef(right, expression);
2941
  } else {
2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952
    fni_.RemoveLastFunction();
  }

  if (op == Token::ASSIGN) {
    // 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.
    if (impl()->IsThisProperty(expression)) function_state_->AddProperty();
  } else {
    // Only initializers (i.e. no compound assignments) are allowed in patterns.
2953 2954
    expression_scope()->RecordPatternError(
        Scanner::Location(lhs_beg_pos, end_position()),
2955
        MessageTemplate::kInvalidDestructuringTarget);
2956 2957
  }

2958
  return factory()->NewAssignment(op, expression, right, op_position);
2959 2960
}

2961
template <typename Impl>
2962 2963
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseYieldExpression() {
2964 2965 2966
  // YieldExpression ::
  //   'yield' ([no line terminator] '*'? AssignmentExpression)?
  int pos = peek_position();
2967
  expression_scope()->RecordParameterInitializerError(
2968
      scanner()->peek_location(), MessageTemplate::kYieldInParameter);
2969
  Consume(Token::YIELD);
2970 2971 2972
  if (V8_UNLIKELY(scanner()->literal_contains_escapes())) {
    impl()->ReportUnexpectedToken(Token::ESCAPED_KEYWORD);
  }
2973 2974 2975

  CheckStackOverflow();

2976
  // The following initialization is necessary.
2977
  ExpressionT expression = impl()->NullExpression();
2978
  bool delegating = false;  // yield*
2979
  if (!scanner()->HasLineTerminatorBeforeNext()) {
2980
    if (Check(Token::MUL)) delegating = true;
2981 2982 2983 2984 2985 2986 2987 2988
    switch (peek()) {
      case Token::EOS:
      case Token::SEMICOLON:
      case Token::RBRACE:
      case Token::RBRACK:
      case Token::RPAREN:
      case Token::COLON:
      case Token::COMMA:
2989
      case Token::IN:
2990 2991 2992
        // 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
2993 2994
        // a regular yield, given only one look-ahead token.
        if (!delegating) break;
2995
        // Delegating yields require an RHS; fall through.
2996
        V8_FALLTHROUGH;
2997
      default:
2998
        expression = ParseAssignmentExpressionCoverGrammar();
2999 3000 3001
        break;
    }
  }
3002 3003

  if (delegating) {
3004 3005
    ExpressionT yieldstar = factory()->NewYieldStar(expression, pos);
    impl()->RecordSuspendSourceRange(yieldstar, PositionAfterSemicolon());
3006 3007
    function_state_->AddSuspend();
    if (IsAsyncGeneratorFunction(function_state_->kind())) {
3008 3009
      // return, iterator_close and delegated_iterator_output suspend ids.
      function_state_->AddSuspend();
3010 3011 3012
      function_state_->AddSuspend();
      function_state_->AddSuspend();
    }
3013
    return yieldstar;
3014
  }
3015

3016 3017
  // Hackily disambiguate o from o.next and o [Symbol.iterator]().
  // TODO(verwaest): Come up with a better solution.
3018 3019
  ExpressionT yield =
      factory()->NewYield(expression, pos, Suspend::kOnExceptionThrow);
3020
  impl()->RecordSuspendSourceRange(yield, PositionAfterSemicolon());
3021
  function_state_->AddSuspend();
3022 3023 3024 3025
  return yield;
}

// Precedence = 3
3026 3027
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
3028
ParserBase<Impl>::ParseConditionalExpression() {
3029
  // ConditionalExpression ::
3030 3031 3032
  //   LogicalExpression
  //   LogicalExpression '?' AssignmentExpression ':' AssignmentExpression
  //
3033
  int pos = peek_position();
3034
  ExpressionT expression = ParseLogicalExpression();
3035
  return peek() == Token::CONDITIONAL
3036
             ? ParseConditionalContinuation(expression, pos)
3037
             : expression;
3038 3039
}

3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseLogicalExpression() {
  // LogicalExpression ::
  //   LogicalORExpression
  //   CoalesceExpression

  // Both LogicalORExpression and CoalesceExpression start with BitwiseOR.
  // Parse for binary expressions >= 6 (BitwiseOR);
  ExpressionT expression = ParseBinaryExpression(6);
  if (peek() == Token::AND || peek() == Token::OR) {
    // LogicalORExpression, pickup parsing where we left off.
    int prec1 = Token::Precedence(peek(), accept_IN_);
    expression = ParseBinaryContinuation(expression, 4, prec1);
  } else if (V8_UNLIKELY(peek() == Token::NULLISH)) {
    expression = ParseCoalesceExpression(expression);
  }
  return expression;
}

template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseCoalesceExpression(ExpressionT expression) {
  // CoalesceExpression ::
  //   CoalesceExpressionHead ?? BitwiseORExpression
  //
  //   CoalesceExpressionHead ::
  //     CoalesceExpression
  //     BitwiseORExpression

  // We create a binary operation for the first nullish, otherwise collapse
  // into an nary expresion.
  bool first_nullish = true;
  while (peek() == Token::NULLISH) {
    SourceRange right_range;
3075 3076 3077 3078 3079 3080 3081 3082 3083
    int pos;
    ExpressionT y;
    {
      SourceRangeScope right_range_scope(scanner(), &right_range);
      Consume(Token::NULLISH);
      pos = peek_position();
      // Parse BitwiseOR or higher.
      y = ParseBinaryExpression(6);
    }
3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096
    if (first_nullish) {
      expression =
          factory()->NewBinaryOperation(Token::NULLISH, expression, y, pos);
      impl()->RecordBinaryOperationSourceRange(expression, right_range);
      first_nullish = false;
    } else {
      impl()->CollapseNaryExpression(&expression, y, Token::NULLISH, pos,
                                     right_range);
    }
  }
  return expression;
}

3097 3098 3099
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseConditionalContinuation(ExpressionT expression,
3100
                                               int pos) {
3101
  SourceRange then_range, else_range;
3102 3103 3104

  ExpressionT left;
  {
3105
    SourceRangeScope range_scope(scanner(), &then_range);
3106
    Consume(Token::CONDITIONAL);
3107 3108 3109
    // In parsing the first assignment expression in conditional
    // expressions we always accept the 'in' keyword; see ECMA-262,
    // section 11.12, page 58.
3110 3111
    AcceptINScope scope(this, true);
    left = ParseAssignmentExpression();
3112 3113 3114
  }
  ExpressionT right;
  {
3115
    SourceRangeScope range_scope(scanner(), &else_range);
3116
    Expect(Token::COLON);
3117
    right = ParseAssignmentExpression();
3118
  }
3119 3120 3121
  ExpressionT expr = factory()->NewConditional(expression, left, right, pos);
  impl()->RecordConditionalSourceRange(expr, then_range, else_range);
  return expr;
3122 3123 3124
}

// Precedence >= 4
3125
template <typename Impl>
3126
typename ParserBase<Impl>::ExpressionT
3127
ParserBase<Impl>::ParseBinaryContinuation(ExpressionT x, int prec, int prec1) {
3128
  do {
3129
    // prec1 >= 4
3130
    while (Token::Precedence(peek(), accept_IN_) == prec1) {
3131 3132 3133 3134 3135 3136 3137 3138 3139 3140
      SourceRange right_range;
      int pos = peek_position();
      ExpressionT y;
      Token::Value op;
      {
        SourceRangeScope right_range_scope(scanner(), &right_range);
        op = Next();

        const bool is_right_associative = op == Token::EXP;
        const int next_prec = is_right_associative ? prec1 : prec1 + 1;
3141
        y = ParseBinaryExpression(next_prec);
3142
      }
3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154

      // 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;
        }
3155 3156 3157 3158
        x = factory()->NewCompareOperation(cmp, x, y, pos);
        if (cmp != op) {
          // The comparison was negated - add a NOT.
          x = factory()->NewUnaryOperation(Token::NOT, x, pos);
3159
        }
3160 3161 3162
      } else if (!impl()->ShortcutNumericLiteralBinaryExpression(&x, y, op,
                                                                 pos) &&
                 !impl()->CollapseNaryExpression(&x, y, op, pos, right_range)) {
3163 3164
        // We have a "normal" binary operation.
        x = factory()->NewBinaryOperation(op, x, y, pos);
3165 3166 3167
        if (op == Token::OR || op == Token::AND) {
          impl()->RecordBinaryOperationSourceRange(x, right_range);
        }
3168 3169
      }
    }
3170 3171 3172 3173 3174 3175 3176 3177 3178
    --prec1;
  } while (prec1 >= prec);

  return x;
}

// Precedence >= 4
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBinaryExpression(
3179
    int prec) {
3180
  DCHECK_GE(prec, 4);
3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194
  ExpressionT x;
  // "#foo in ShiftExpression" needs to be parsed separately, since private
  // identifiers are not valid PrimaryExpressions.
  if (V8_UNLIKELY(FLAG_harmony_private_brand_checks &&
                  peek() == Token::PRIVATE_NAME)) {
    x = ParsePropertyOrPrivatePropertyName();
    if (peek() != Token::IN) {
      ReportUnexpectedToken(peek());
      return impl()->FailureExpression();
    }
  } else {
    x = ParseUnaryExpression();
  }

3195
  int prec1 = Token::Precedence(peek(), accept_IN_);
3196
  if (prec1 >= prec) {
3197
    return ParseBinaryContinuation(x, prec, prec1);
3198 3199 3200 3201
  }
  return x;
}

3202
template <typename Impl>
3203
typename ParserBase<Impl>::ExpressionT
3204
ParserBase<Impl>::ParseUnaryOrPrefixExpression() {
3205 3206 3207 3208 3209 3210 3211 3212
  Token::Value op = Next();
  int pos = position();

  // 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();
  }

3213 3214
  CheckStackOverflow();

3215
  int expression_position = peek_position();
3216
  ExpressionT expression = ParseUnaryExpression();
3217

3218 3219 3220 3221 3222 3223 3224 3225
  if (Token::IsUnaryOp(op)) {
    if (op == Token::DELETE) {
      if (impl()->IsIdentifier(expression) && is_strict(language_mode())) {
        // "delete identifier" is a syntax error in strict mode.
        ReportMessage(MessageTemplate::kStrictDelete);
        return impl()->FailureExpression();
      }

3226
      if (impl()->IsPrivateReference(expression)) {
3227 3228 3229
        ReportMessage(MessageTemplate::kDeletePrivateField);
        return impl()->FailureExpression();
      }
3230 3231
    }

3232
    if (peek() == Token::EXP) {
3233 3234 3235
      impl()->ReportMessageAt(
          Scanner::Location(pos, peek_end_position()),
          MessageTemplate::kUnexpectedTokenUnaryExponentiation);
3236
      return impl()->FailureExpression();
3237 3238
    }

3239 3240
    // Allow the parser's implementation to rewrite the expression.
    return impl()->BuildUnaryExpression(expression, op, pos);
3241 3242
  }

3243
  DCHECK(Token::IsCountOp(op));
3244

3245
  if (V8_LIKELY(IsValidReferenceExpression(expression))) {
3246 3247 3248
    if (impl()->IsIdentifier(expression)) {
      expression_scope()->MarkIdentifierAsAssigned();
    }
3249
  } else {
3250
    const bool early_error = false;
3251
    expression = RewriteInvalidReferenceExpression(
3252
        expression, expression_position, end_position(),
3253
        MessageTemplate::kInvalidLhsInPrefixOp, early_error);
3254
  }
3255 3256 3257 3258 3259 3260

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

template <typename Impl>
3261 3262
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseAwaitExpression() {
3263
  expression_scope()->RecordParameterInitializerError(
3264 3265 3266 3267
      scanner()->peek_location(),
      MessageTemplate::kAwaitExpressionFormalParameter);
  int await_pos = peek_position();
  Consume(Token::AWAIT);
3268 3269 3270
  if (V8_UNLIKELY(scanner()->literal_contains_escapes())) {
    impl()->ReportUnexpectedToken(Token::ESCAPED_KEYWORD);
  }
3271

3272 3273
  CheckStackOverflow();

3274
  ExpressionT value = ParseUnaryExpression();
3275

3276 3277 3278 3279 3280 3281 3282 3283 3284
  // 'await' is a unary operator according to the spec, even though it's treated
  // specially in the parser.
  if (peek() == Token::EXP) {
    impl()->ReportMessageAt(
        Scanner::Location(await_pos, peek_end_position()),
        MessageTemplate::kUnexpectedTokenUnaryExponentiation);
    return impl()->FailureExpression();
  }

3285 3286 3287 3288 3289 3290
  ExpressionT expr = factory()->NewAwait(value, await_pos);
  function_state_->AddSuspend();
  impl()->RecordSuspendSourceRange(expr, PositionAfterSemicolon());
  return expr;
}

3291
template <typename Impl>
3292 3293
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseUnaryExpression() {
3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304
  // UnaryExpression ::
  //   PostfixExpression
  //   'delete' UnaryExpression
  //   'void' UnaryExpression
  //   'typeof' UnaryExpression
  //   '++' UnaryExpression
  //   '--' UnaryExpression
  //   '+' UnaryExpression
  //   '-' UnaryExpression
  //   '~' UnaryExpression
  //   '!' UnaryExpression
3305
  //   [+Await] AwaitExpression[?Yield]
3306 3307

  Token::Value op = peek();
3308
  if (Token::IsUnaryOrCountOp(op)) return ParseUnaryOrPrefixExpression();
3309
  if (is_await_allowed() && op == Token::AWAIT) {
3310
    return ParseAwaitExpression();
3311
  }
3312
  return ParsePostfixExpression();
3313 3314
}

3315
template <typename Impl>
3316 3317
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParsePostfixExpression() {
3318 3319 3320 3321
  // PostfixExpression ::
  //   LeftHandSideExpression ('++' | '--')?

  int lhs_beg_pos = peek_position();
3322
  ExpressionT expression = ParseLeftHandSideExpression();
3323 3324 3325 3326 3327 3328
  if (V8_LIKELY(!Token::IsCountOp(peek()) ||
                scanner()->HasLineTerminatorBeforeNext())) {
    return expression;
  }
  return ParsePostfixContinuation(expression, lhs_beg_pos);
}
3329

3330 3331 3332 3333 3334
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParsePostfixContinuation(ExpressionT expression,
                                           int lhs_beg_pos) {
  if (V8_UNLIKELY(!IsValidReferenceExpression(expression))) {
3335
    const bool early_error = false;
3336 3337
    expression = RewriteInvalidReferenceExpression(
        expression, lhs_beg_pos, end_position(),
3338
        MessageTemplate::kInvalidLhsInPostfixOp, early_error);
3339 3340 3341
  }
  if (impl()->IsIdentifier(expression)) {
    expression_scope()->MarkIdentifierAsAssigned();
3342
  }
3343 3344 3345 3346

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

3349 3350
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
3351
ParserBase<Impl>::ParseLeftHandSideExpression() {
3352 3353 3354
  // LeftHandSideExpression ::
  //   (NewExpression | MemberExpression) ...

3355
  ExpressionT result = ParseMemberExpression();
3356
  if (!Token::IsPropertyOrCall(peek())) return result;
3357
  return ParseLeftHandSideContinuation(result);
3358
}
3359

3360 3361
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
3362
ParserBase<Impl>::ParseLeftHandSideContinuation(ExpressionT result) {
3363
  DCHECK(Token::IsPropertyOrCall(peek()));
3364 3365 3366

  if (V8_UNLIKELY(peek() == Token::LPAREN && impl()->IsIdentifier(result) &&
                  scanner()->current_token() == Token::ASYNC &&
3367 3368
                  !scanner()->HasLineTerminatorBeforeNext() &&
                  !scanner()->literal_contains_escapes())) {
3369 3370 3371
    DCHECK(impl()->IsAsync(impl()->AsIdentifier(result)));
    int pos = position();

3372 3373
    ArrowHeadParsingScope maybe_arrow(impl(),
                                      FunctionKind::kAsyncArrowFunction);
3374 3375
    Scope::Snapshot scope_snapshot(scope());

3376 3377
    ExpressionListT args(pointer_buffer());
    bool has_spread;
3378
    ParseArguments(&args, &has_spread, kMaybeArrowHead);
3379 3380
    if (V8_LIKELY(peek() == Token::ARROW)) {
      fni_.RemoveAsyncKeywordFromEnd();
3381
      next_arrow_function_info_.scope = maybe_arrow.ValidateAndCreateScope();
3382
      scope_snapshot.Reparent(next_arrow_function_info_.scope);
3383 3384 3385 3386 3387 3388
      // async () => ...
      if (!args.length()) return factory()->NewEmptyParentheses(pos);
      // async ( Arguments ) => ...
      ExpressionT result = impl()->ExpressionListToExpression(args);
      result->mark_parenthesized();
      return result;
3389 3390
    }

3391
    result = factory()->NewCall(result, args, pos, has_spread);
3392

3393 3394
    maybe_arrow.ValidateExpression();

3395 3396 3397
    fni_.RemoveLastFunction();
    if (!Token::IsPropertyOrCall(peek())) return result;
  }
3398

3399 3400
  bool optional_chaining = false;
  bool is_optional = false;
3401
  int optional_link_begin;
3402
  do {
3403
    switch (peek()) {
3404 3405 3406 3407 3408
      case Token::QUESTION_PERIOD: {
        if (is_optional) {
          ReportUnexpectedToken(peek());
          return impl()->FailureExpression();
        }
3409 3410
        // Include the ?. in the source range position.
        optional_link_begin = scanner()->peek_location().beg_pos;
3411 3412 3413
        Consume(Token::QUESTION_PERIOD);
        is_optional = true;
        optional_chaining = true;
3414 3415 3416 3417 3418
        if (Token::IsPropertyOrCall(peek())) continue;
        int pos = position();
        ExpressionT key = ParsePropertyOrPrivatePropertyName();
        result = factory()->NewProperty(result, key, pos, is_optional);
        break;
3419 3420
      }

3421
      /* Property */
3422 3423 3424
      case Token::LBRACK: {
        Consume(Token::LBRACK);
        int pos = position();
3425 3426
        AcceptINScope scope(this, true);
        ExpressionT index = ParseExpressionCoverGrammar();
3427
        result = factory()->NewProperty(result, index, pos, is_optional);
3428
        Expect(Token::RBRACK);
3429 3430 3431
        break;
      }

3432 3433
      /* Property */
      case Token::PERIOD: {
3434 3435 3436 3437
        if (is_optional) {
          ReportUnexpectedToken(Next());
          return impl()->FailureExpression();
        }
3438 3439
        Consume(Token::PERIOD);
        int pos = position();
3440
        ExpressionT key = ParsePropertyOrPrivatePropertyName();
3441
        result = factory()->NewProperty(result, key, pos, is_optional);
3442 3443 3444 3445
        break;
      }

      /* Call */
3446
      case Token::LPAREN: {
3447
        int pos;
3448
        if (Token::IsCallable(scanner()->current_token())) {
3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461
          // 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.
3462
          if (result->IsFunctionLiteral()) {
3463
            result->AsFunctionLiteral()->SetShouldEagerCompile();
3464 3465 3466 3467 3468
            if (scope()->is_script_scope()) {
              // A non-top-level iife is likely to be executed multiple times
              // and so shouldn`t be optimized as one-shot.
              result->AsFunctionLiteral()->mark_as_oneshot_iife();
            }
3469 3470
          }
        }
3471
        bool has_spread;
3472
        ExpressionListT args(pointer_buffer());
3473
        ParseArguments(&args, &has_spread);
3474 3475 3476 3477 3478 3479 3480 3481

        // 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.
3482
        Call::PossiblyEval is_possibly_eval =
3483
            CheckPossibleEvalCall(result, is_optional, scope());
3484

3485 3486
        result = factory()->NewCall(result, args, pos, has_spread,
                                    is_possibly_eval, is_optional);
3487

3488
        fni_.RemoveLastFunction();
3489 3490 3491
        break;
      }

3492
      default:
3493
        // Template literals in/after an Optional Chain not supported:
3494 3495 3496 3497 3498 3499
        if (optional_chaining) {
          impl()->ReportMessageAt(scanner()->peek_location(),
                                  MessageTemplate::kOptionalChainingNoTemplate);
          return impl()->FailureExpression();
        }
        /* Tagged Template */
3500
        DCHECK(Token::IsTemplate(peek()));
3501
        result = ParseTemplateLiteral(result, position(), true);
3502 3503
        break;
    }
3504 3505 3506 3507 3508 3509
    if (is_optional) {
      SourceRange chain_link_range(optional_link_begin, end_position());
      impl()->RecordExpressionSourceRange(result, chain_link_range);
      is_optional = false;
    }
  } while (Token::IsPropertyOrCall(peek()));
3510
  if (optional_chaining) return factory()->NewOptionalChain(result);
3511
  return result;
3512 3513
}

3514 3515
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
3516
ParserBase<Impl>::ParseMemberWithPresentNewPrefixesExpression() {
3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535
  // 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
3536
  // new super.x means new (super.x)
3537 3538 3539
  Consume(Token::NEW);
  int new_pos = position();
  ExpressionT result;
3540 3541 3542

  CheckStackOverflow();

3543
  if (peek() == Token::IMPORT && PeekAhead() == Token::LPAREN) {
3544 3545
    impl()->ReportMessageAt(scanner()->peek_location(),
                            MessageTemplate::kImportCallNotNewExpression);
3546
    return impl()->FailureExpression();
3547
  } else if (peek() == Token::PERIOD) {
3548 3549
    result = ParseNewTargetExpression();
    return ParseMemberExpressionContinuation(result);
3550
  } else {
3551
    result = ParseMemberExpression();
3552 3553 3554 3555 3556 3557
    if (result->IsSuperCallReference()) {
      // new super() is never allowed
      impl()->ReportMessageAt(scanner()->location(),
                              MessageTemplate::kUnexpectedSuper);
      return impl()->FailureExpression();
    }
3558 3559 3560
  }
  if (peek() == Token::LPAREN) {
    // NewExpression with arguments.
3561
    {
3562
      ExpressionListT args(pointer_buffer());
3563
      bool has_spread;
3564
      ParseArguments(&args, &has_spread);
3565

3566
      result = factory()->NewCallNew(result, args, new_pos, has_spread);
3567
    }
3568
    // The expression can still continue with . or [ after the arguments.
3569
    return ParseMemberExpressionContinuation(result);
3570
  }
3571 3572 3573 3574 3575 3576 3577

  if (peek() == Token::QUESTION_PERIOD) {
    impl()->ReportMessageAt(scanner()->peek_location(),
                            MessageTemplate::kOptionalChainingNoNew);
    return impl()->FailureExpression();
  }

3578
  // NewExpression without arguments.
3579
  ExpressionListT args(pointer_buffer());
3580
  return factory()->NewCallNew(result, args, new_pos, false);
3581 3582
}

3583 3584
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
3585
ParserBase<Impl>::ParseFunctionExpression() {
3586 3587 3588 3589 3590 3591 3592
  Consume(Token::FUNCTION);
  int function_token_position = position();

  FunctionKind function_kind = Check(Token::MUL)
                                   ? FunctionKind::kGeneratorFunction
                                   : FunctionKind::kNormalFunction;
  IdentifierT name = impl()->NullIdentifier();
3593
  bool is_strict_reserved_name = Token::IsStrictReservedWord(peek());
3594
  Scanner::Location function_name_location = Scanner::Location::invalid();
3595 3596
  FunctionSyntaxKind function_syntax_kind =
      FunctionSyntaxKind::kAnonymousExpression;
3597 3598 3599 3600
  if (impl()->ParsingDynamicFunctionDeclaration()) {
    // We don't want dynamic functions to actually declare their name
    // "anonymous". We just want that name in the toString().
    Consume(Token::IDENTIFIER);
3601
    DCHECK_IMPLIES(!has_error(),
3602 3603
                   scanner()->CurrentSymbol(ast_value_factory()) ==
                       ast_value_factory()->anonymous_string());
3604
  } else if (peek_any_identifier()) {
3605
    name = ParseIdentifier(function_kind);
3606
    function_name_location = scanner()->location();
3607
    function_syntax_kind = FunctionSyntaxKind::kNamedExpression;
3608
  }
3609 3610 3611 3612
  FunctionLiteralT result = impl()->ParseFunctionLiteral(
      name, function_name_location,
      is_strict_reserved_name ? kFunctionNameIsStrictReserved
                              : kFunctionNameValidityUnknown,
3613 3614
      function_kind, function_token_position, function_syntax_kind,
      language_mode(), nullptr);
3615 3616 3617
  // TODO(verwaest): FailureFunctionLiteral?
  if (impl()->IsNull(result)) return impl()->FailureExpression();
  return result;
3618 3619
}

3620
template <typename Impl>
3621 3622
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseMemberExpression() {
3623 3624 3625
  // MemberExpression ::
  //   (PrimaryExpression | FunctionLiteral | ClassLiteral)
  //     ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
3626 3627 3628 3629 3630
  //
  // CallExpression ::
  //   (SuperCall | ImportCall)
  //     ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
  //
3631
  // The '[' Expression ']' and '.' Identifier parts are parsed by
3632 3633
  // ParseMemberExpressionContinuation, and everything preceeding it is merged
  // into ParsePrimaryExpression.
3634 3635

  // Parse the initial primary or function expression.
3636
  ExpressionT result = ParsePrimaryExpression();
3637
  return ParseMemberExpressionContinuation(result);
3638 3639
}

3640
template <typename Impl>
3641 3642
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseImportExpressions() {
3643 3644
  Consume(Token::IMPORT);
  int pos = position();
3645
  if (Check(Token::PERIOD)) {
3646 3647
    ExpectContextualKeyword(ast_value_factory()->meta_string(), "import.meta",
                            pos);
3648
    if (!flags().is_module()) {
3649 3650
      impl()->ReportMessageAt(scanner()->location(),
                              MessageTemplate::kImportMetaOutsideModule);
3651
      return impl()->FailureExpression();
3652 3653
    }

3654
    return impl()->ImportMetaExpression(pos);
3655
  }
3656 3657

  if (V8_UNLIKELY(peek() != Token::LPAREN)) {
3658
    if (!flags().is_module()) {
3659 3660 3661 3662 3663 3664 3665 3666 3667
      impl()->ReportMessageAt(scanner()->location(),
                              MessageTemplate::kImportOutsideModule);
    } else {
      ReportUnexpectedToken(Next());
    }
    return impl()->FailureExpression();
  }

  Consume(Token::LPAREN);
3668 3669 3670
  if (peek() == Token::RPAREN) {
    impl()->ReportMessageAt(scanner()->location(),
                            MessageTemplate::kImportMissingSpecifier);
3671
    return impl()->FailureExpression();
3672
  }
3673

3674
  AcceptINScope scope(this, true);
3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689
  ExpressionT specifier = ParseAssignmentExpressionCoverGrammar();

  if (FLAG_harmony_import_assertions && Check(Token::COMMA)) {
    if (Check(Token::RPAREN)) {
      // A trailing comma allowed after the specifier.
      return factory()->NewImportCallExpression(specifier, pos);
    } else {
      ExpressionT import_assertions = ParseAssignmentExpressionCoverGrammar();
      Check(Token::COMMA);  // A trailing comma is allowed after the import
                            // assertions.
      Expect(Token::RPAREN);
      return factory()->NewImportCallExpression(specifier, import_assertions,
                                                pos);
    }
  }
3690

3691 3692
  Expect(Token::RPAREN);
  return factory()->NewImportCallExpression(specifier, pos);
3693 3694
}

3695
template <typename Impl>
3696 3697
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseSuperExpression() {
3698
  Consume(Token::SUPER);
3699 3700
  int pos = position();

3701
  DeclarationScope* scope = GetReceiverScope();
3702 3703 3704
  FunctionKind kind = scope->function_kind();
  if (IsConciseMethod(kind) || IsAccessorFunction(kind) ||
      IsClassConstructor(kind)) {
3705
    if (Token::IsProperty(peek())) {
3706 3707 3708 3709 3710 3711 3712
      if (peek() == Token::PERIOD && PeekAhead() == Token::PRIVATE_NAME) {
        Consume(Token::PERIOD);
        Consume(Token::PRIVATE_NAME);

        impl()->ReportMessage(MessageTemplate::kUnexpectedPrivateField);
        return impl()->FailureExpression();
      }
3713 3714 3715 3716 3717
      if (peek() == Token::QUESTION_PERIOD) {
        Consume(Token::QUESTION_PERIOD);
        impl()->ReportMessage(MessageTemplate::kOptionalChainingNoSuper);
        return impl()->FailureExpression();
      }
3718
      scope->RecordSuperPropertyUsage();
3719
      UseThis();
3720
      return impl()->NewSuperPropertyReference(pos);
3721
    }
3722 3723 3724 3725
    // super() is only allowed in derived constructor. new super() is never
    // allowed; it's reported as an error by
    // ParseMemberWithPresentNewPrefixesExpression.
    if (peek() == Token::LPAREN && IsDerivedConstructor(kind)) {
3726 3727
      // TODO(rossberg): This might not be the correct FunctionState for the
      // method here.
3728 3729
      expression_scope()->RecordThisUse();
      UseThis();
3730
      return impl()->NewSuperCallReference(pos);
3731 3732 3733
    }
  }

3734 3735
  impl()->ReportMessageAt(scanner()->location(),
                          MessageTemplate::kUnexpectedSuper);
3736
  return impl()->FailureExpression();
3737 3738
}

3739 3740
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
3741
ParserBase<Impl>::ParseNewTargetExpression() {
3742
  int pos = position();
3743 3744 3745
  Consume(Token::PERIOD);
  ExpectContextualKeyword(ast_value_factory()->target_string(), "new.target",
                          pos);
3746

3747
  if (!GetReceiverScope()->is_function_scope()) {
3748 3749
    impl()->ReportMessageAt(scanner()->location(),
                            MessageTemplate::kUnexpectedNewTarget);
3750
    return impl()->FailureExpression();
3751 3752
  }

3753
  return impl()->NewTargetExpression(pos);
3754 3755
}

3756 3757
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
3758
ParserBase<Impl>::DoParseMemberExpressionContinuation(ExpressionT expression) {
3759
  DCHECK(Token::IsMember(peek()));
3760 3761
  // Parses this part of MemberExpression:
  // ('[' Expression ']' | '.' Identifier | TemplateLiteral)*
3762
  do {
3763 3764 3765 3766
    switch (peek()) {
      case Token::LBRACK: {
        Consume(Token::LBRACK);
        int pos = position();
3767 3768
        AcceptINScope scope(this, true);
        ExpressionT index = ParseExpressionCoverGrammar();
3769
        expression = factory()->NewProperty(expression, index, pos);
3770
        impl()->PushPropertyName(index);
3771
        Expect(Token::RBRACK);
3772 3773 3774 3775
        break;
      }
      case Token::PERIOD: {
        Consume(Token::PERIOD);
3776
        int pos = peek_position();
3777
        ExpressionT key = ParsePropertyOrPrivatePropertyName();
3778
        expression = factory()->NewProperty(expression, key, pos);
3779 3780
        break;
      }
3781
      default: {
3782
        DCHECK(Token::IsTemplate(peek()));
3783 3784 3785 3786 3787
        int pos;
        if (scanner()->current_token() == Token::IDENTIFIER) {
          pos = position();
        } else {
          pos = peek_position();
3788
          if (expression->IsFunctionLiteral()) {
3789 3790
            // If the tag function looks like an IIFE, set_parenthesized() to
            // force eager compilation.
3791
            expression->AsFunctionLiteral()->SetShouldEagerCompile();
3792 3793
          }
        }
3794
        expression = ParseTemplateLiteral(expression, pos, true);
3795 3796 3797
        break;
      }
    }
3798
  } while (Token::IsMember(peek()));
3799
  return expression;
3800 3801
}

3802
template <typename Impl>
3803
void ParserBase<Impl>::ParseFormalParameter(FormalParametersT* parameters) {
3804 3805
  // FormalParameter[Yield,GeneratorParameter] :
  //   BindingElement[?Yield, ?GeneratorParameter]
3806
  FuncNameInferrerState fni_state(&fni_);
3807
  int pos = peek_position();
3808
  auto declaration_it = scope()->declarations()->end();
3809
  ExpressionT pattern = ParseBindingPattern();
3810
  if (impl()->IsIdentifier(pattern)) {
3811
    ClassifyParameter(impl()->AsIdentifier(pattern), pos, end_position());
3812
  } else {
3813 3814 3815
    parameters->is_simple = false;
  }

3816
  ExpressionT initializer = impl()->NullExpression();
3817
  if (Check(Token::ASSIGN)) {
3818 3819
    parameters->is_simple = false;

3820
    if (parameters->has_rest) {
3821 3822 3823
      ReportMessage(MessageTemplate::kRestDefaultInitializer);
      return;
    }
3824

3825
    AcceptINScope accept_in_scope(this, true);
3826
    initializer = ParseAssignmentExpression();
3827
    impl()->SetFunctionNameFromIdentifierRef(initializer, pattern);
3828 3829
  }

3830 3831 3832
  auto declaration_end = scope()->declarations()->end();
  int initializer_end = end_position();
  for (; declaration_it != declaration_end; ++declaration_it) {
3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845
    Variable* var = declaration_it->var();

    // The first time a variable is initialized (i.e. when the initializer
    // position is unset), clear its maybe_assigned flag as it is not a true
    // assignment. Since this is done directly on the Variable objects, it has
    // no effect on VariableProxy objects appearing on the left-hand side of
    // true assignments, so x will be still be marked as maybe_assigned for:
    // (x = 1, y = (x = 2)) => {}
    // and even:
    // (x = (x = 2)) => {}.
    if (var->initializer_position() == kNoSourcePosition)
      var->clear_maybe_assigned();
    var->set_initializer_position(initializer_end);
3846 3847
  }

3848
  impl()->AddFormalParameter(parameters, pattern, initializer, end_position(),
3849
                             parameters->has_rest);
3850 3851
}

3852
template <typename Impl>
3853
void ParserBase<Impl>::ParseFormalParameterList(FormalParametersT* parameters) {
3854
  // FormalParameters[Yield] :
3855 3856
  //   [empty]
  //   FunctionRestParameter[?Yield]
3857 3858 3859
  //   FormalParameterList[?Yield]
  //   FormalParameterList[?Yield] ,
  //   FormalParameterList[?Yield] , FunctionRestParameter[?Yield]
3860
  //
3861 3862 3863
  // FormalParameterList[Yield] :
  //   FormalParameter[?Yield]
  //   FormalParameterList[?Yield] , FormalParameter[?Yield]
3864
  ParameterParsingScope scope(impl(), parameters);
3865

3866
  DCHECK_EQ(0, parameters->arity);
3867 3868

  if (peek() != Token::RPAREN) {
3869
    while (true) {
3870 3871
      // Add one since we're going to be adding a parameter.
      if (parameters->arity + 1 > Code::kMaxArguments) {
3872 3873 3874
        ReportMessage(MessageTemplate::kTooManyParameters);
        return;
      }
3875
      parameters->has_rest = Check(Token::ELLIPSIS);
3876
      ParseFormalParameter(parameters);
3877

3878 3879 3880
      if (parameters->has_rest) {
        parameters->is_simple = false;
        if (peek() == Token::COMMA) {
3881 3882
          impl()->ReportMessageAt(scanner()->peek_location(),
                                  MessageTemplate::kParamAfterRest);
3883 3884 3885 3886 3887
          return;
        }
        break;
      }
      if (!Check(Token::COMMA)) break;
3888
      if (peek() == Token::RPAREN) {
3889 3890
        // allow the trailing comma
        break;
3891 3892 3893 3894
      }
    }
  }

3895
  impl()->DeclareFormalParameters(parameters);
3896 3897
}

3898
template <typename Impl>
3899
void ParserBase<Impl>::ParseVariableDeclarations(
3900
    VariableDeclarationContext var_context,
3901 3902
    DeclarationParsingResult* parsing_result,
    ZonePtrList<const AstRawString>* names) {
3903 3904 3905 3906 3907 3908 3909
  // VariableDeclarations ::
  //   ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
  //
  // ES6:
  // FIXME(marja, nikolaos): Add an up-to-date comment about ES6 variable
  // declaration syntax.

3910
  DCHECK_NOT_NULL(parsing_result);
3911
  parsing_result->descriptor.kind = NORMAL_VARIABLE;
3912 3913 3914 3915 3916
  parsing_result->descriptor.declaration_pos = peek_position();
  parsing_result->descriptor.initialization_pos = peek_position();

  switch (peek()) {
    case Token::VAR:
3917
      parsing_result->descriptor.mode = VariableMode::kVar;
3918 3919 3920 3921
      Consume(Token::VAR);
      break;
    case Token::CONST:
      Consume(Token::CONST);
3922
      DCHECK_NE(var_context, kStatement);
3923
      parsing_result->descriptor.mode = VariableMode::kConst;
3924 3925 3926
      break;
    case Token::LET:
      Consume(Token::LET);
3927
      DCHECK_NE(var_context, kStatement);
3928
      parsing_result->descriptor.mode = VariableMode::kLet;
3929 3930 3931 3932 3933 3934
      break;
    default:
      UNREACHABLE();  // by current callers
      break;
  }

3935 3936
  VariableDeclarationParsingScope declaration(
      impl(), parsing_result->descriptor.mode, names);
3937 3938 3939 3940 3941
  Scope* target_scope = IsLexicalVariableMode(parsing_result->descriptor.mode)
                            ? scope()
                            : scope()->GetDeclarationScope();

  auto declaration_it = target_scope->declarations()->end();
3942

3943 3944 3945
  int bindings_start = peek_position();
  do {
    // Parse binding pattern.
3946
    FuncNameInferrerState fni_state(&fni_);
3947 3948

    int decl_pos = peek_position();
3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977

    IdentifierT name;
    ExpressionT pattern;
    // Check for an identifier first, so that we can elide the pattern in cases
    // where there is no initializer (and so no proxy needs to be created).
    if (V8_LIKELY(Token::IsAnyIdentifier(peek()))) {
      name = ParseAndClassifyIdentifier(Next());
      if (V8_UNLIKELY(is_strict(language_mode()) &&
                      impl()->IsEvalOrArguments(name))) {
        impl()->ReportMessageAt(scanner()->location(),
                                MessageTemplate::kStrictEvalArguments);
        return;
      }
      if (peek() == Token::ASSIGN ||
          (var_context == kForStatement && PeekInOrOf()) ||
          parsing_result->descriptor.mode == VariableMode::kLet) {
        // Assignments need the variable expression for the assignment LHS, and
        // for of/in will need it later, so create the expression now.
        pattern = impl()->ExpressionFromIdentifier(name, decl_pos);
      } else {
        // Otherwise, elide the variable expression and just declare it.
        impl()->DeclareIdentifier(name, decl_pos);
        pattern = impl()->NullExpression();
      }
    } else {
      name = impl()->NullIdentifier();
      pattern = ParseBindingPattern();
      DCHECK(!impl()->IsIdentifier(pattern));
    }
3978

3979 3980
    Scanner::Location variable_loc = scanner()->location();

3981
    ExpressionT value = impl()->NullExpression();
3982
    int value_beg_pos = kNoSourcePosition;
3983
    if (Check(Token::ASSIGN)) {
3984
      DCHECK(!impl()->IsNull(pattern));
3985
      {
3986
        value_beg_pos = peek_position();
3987 3988 3989
        AcceptINScope scope(this, var_context != kForStatement);
        value = ParseAssignmentExpression();
      }
3990
      variable_loc.end_pos = end_position();
3991 3992 3993 3994 3995 3996

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

      // Don't infer if it is "a = function(){...}();"-like expression.
3997
      if (impl()->IsIdentifier(pattern)) {
3998
        if (!value->IsCall() && !value->IsCallNew()) {
3999
          fni_.Infer();
4000
        } else {
4001
          fni_.RemoveLastFunction();
4002 4003 4004 4005 4006
        }
      }

      impl()->SetFunctionNameFromIdentifierRef(value, pattern);
    } else {
4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027
#ifdef DEBUG
      // We can fall through into here on error paths, so don't DCHECK those.
      if (!has_error()) {
        // We should never get identifier patterns for the non-initializer path,
        // as those expressions should be elided.
        DCHECK_EQ(!impl()->IsNull(name),
                  Token::IsAnyIdentifier(scanner()->current_token()));
        DCHECK_IMPLIES(impl()->IsNull(pattern), !impl()->IsNull(name));
        // The only times we have a non-null pattern are:
        //   1. This is a destructuring declaration (with no initializer, which
        //      is immediately an error),
        //   2. This is a declaration in a for in/of loop, or
        //   3. This is a let (which has an implicit undefined initializer)
        DCHECK_IMPLIES(
            !impl()->IsNull(pattern),
            !impl()->IsIdentifier(pattern) ||
                (var_context == kForStatement && PeekInOrOf()) ||
                parsing_result->descriptor.mode == VariableMode::kLet);
      }
#endif

4028 4029
      if (var_context != kForStatement || !PeekInOrOf()) {
        // ES6 'const' and binding patterns require initializers.
4030
        if (parsing_result->descriptor.mode == VariableMode::kConst ||
4031
            impl()->IsNull(name)) {
4032
          impl()->ReportMessageAt(
4033
              Scanner::Location(decl_pos, end_position()),
4034
              MessageTemplate::kDeclarationMissingInitializer,
4035
              impl()->IsNull(name) ? "destructuring" : "const");
4036
          return;
4037 4038
        }
        // 'let x' initializes 'x' to undefined.
4039
        if (parsing_result->descriptor.mode == VariableMode::kLet) {
4040
          value = factory()->NewUndefinedLiteral(position());
4041 4042
        }
      }
4043
    }
4044

4045 4046 4047 4048
    int initializer_position = end_position();
    auto declaration_end = target_scope->declarations()->end();
    for (; declaration_it != declaration_end; ++declaration_it) {
      declaration_it->var()->set_initializer_position(initializer_position);
4049 4050
    }

4051 4052 4053 4054 4055
    // Patterns should be elided iff. they don't have an initializer.
    DCHECK_IMPLIES(impl()->IsNull(pattern),
                   impl()->IsNull(value) ||
                       (var_context == kForStatement && PeekInOrOf()));

4056 4057 4058 4059
    typename DeclarationParsingResult::Declaration decl(pattern, value);
    decl.value_beg_pos = value_beg_pos;

    parsing_result->declarations.push_back(decl);
4060 4061 4062
  } while (Check(Token::COMMA));

  parsing_result->bindings_loc =
4063
      Scanner::Location(bindings_start, end_position());
4064 4065
}

4066 4067
template <typename Impl>
typename ParserBase<Impl>::StatementT
4068
ParserBase<Impl>::ParseFunctionDeclaration() {
4069
  Consume(Token::FUNCTION);
4070

4071
  int pos = position();
4072
  ParseFunctionFlags flags = ParseFunctionFlag::kIsNormal;
4073
  if (Check(Token::MUL)) {
4074 4075 4076
    impl()->ReportMessageAt(
        scanner()->location(),
        MessageTemplate::kGeneratorInSingleStatementContext);
4077
    return impl()->NullStatement();
4078
  }
4079
  return ParseHoistableDeclaration(pos, flags, nullptr, false);
4080 4081
}

4082 4083 4084
template <typename Impl>
typename ParserBase<Impl>::StatementT
ParserBase<Impl>::ParseHoistableDeclaration(
4085
    ZonePtrList<const AstRawString>* names, bool default_export) {
4086
  Consume(Token::FUNCTION);
4087

4088
  int pos = position();
4089
  ParseFunctionFlags flags = ParseFunctionFlag::kIsNormal;
4090
  if (Check(Token::MUL)) {
4091
    flags |= ParseFunctionFlag::kIsGenerator;
4092
  }
4093
  return ParseHoistableDeclaration(pos, flags, names, default_export);
4094 4095 4096 4097 4098
}

template <typename Impl>
typename ParserBase<Impl>::StatementT
ParserBase<Impl>::ParseHoistableDeclaration(
4099
    int pos, ParseFunctionFlags flags, ZonePtrList<const AstRawString>* names,
4100
    bool default_export) {
4101 4102
  CheckStackOverflow();

4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113
  // 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.

4114 4115
  DCHECK_IMPLIES((flags & ParseFunctionFlag::kIsAsync) != 0,
                 (flags & ParseFunctionFlag::kIsGenerator) == 0);
4116

4117
  if ((flags & ParseFunctionFlag::kIsAsync) != 0 && Check(Token::MUL)) {
4118
    // Async generator
4119
    flags |= ParseFunctionFlag::kIsGenerator;
4120 4121
  }

4122 4123 4124
  IdentifierT name;
  FunctionNameValidity name_validity;
  IdentifierT variable_name;
4125 4126 4127 4128 4129 4130 4131 4132
  if (peek() == Token::LPAREN) {
    if (default_export) {
      impl()->GetDefaultStrings(&name, &variable_name);
      name_validity = kSkipFunctionNameCheck;
    } else {
      ReportMessage(MessageTemplate::kMissingFunctionName);
      return impl()->NullStatement();
    }
4133
  } else {
4134 4135
    bool is_strict_reserved = Token::IsStrictReservedWord(peek());
    name = ParseIdentifier();
4136 4137 4138 4139 4140
    name_validity = is_strict_reserved ? kFunctionNameIsStrictReserved
                                       : kFunctionNameValidityUnknown;
    variable_name = name;
  }

4141
  FuncNameInferrerState fni_state(&fni_);
4142
  impl()->PushEnclosingName(name);
4143

4144
  FunctionKind function_kind = FunctionKindFor(flags);
4145

4146
  FunctionLiteralT function = impl()->ParseFunctionLiteral(
4147
      name, scanner()->location(), name_validity, function_kind, pos,
4148
      FunctionSyntaxKind::kDeclaration, language_mode(), nullptr);
4149

4150 4151 4152
  // 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 =
4153 4154 4155
      (!scope()->is_declaration_scope() || scope()->is_module_scope())
          ? VariableMode::kLet
          : VariableMode::kVar;
4156 4157
  // Async functions don't undergo sloppy mode block scoped hoisting, and don't
  // allow duplicates in a block. Both are represented by the
4158
  // sloppy_block_functions_. Don't add them to the map for async functions.
4159 4160
  // Generators are also supposed to be prohibited; currently doing this behind
  // a flag and UseCounting violations to assess web compatibility.
4161 4162 4163 4164 4165 4166 4167 4168
  VariableKind kind = is_sloppy(language_mode()) &&
                              !scope()->is_declaration_scope() &&
                              flags == ParseFunctionFlag::kIsNormal
                          ? SLOPPY_BLOCK_FUNCTION_VARIABLE
                          : NORMAL_VARIABLE;

  return impl()->DeclareFunction(variable_name, function, mode, kind, pos,
                                 end_position(), names);
4169 4170
}

4171 4172
template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseClassDeclaration(
4173
    ZonePtrList<const AstRawString>* names, bool default_export) {
4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192
  // 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();
4193
  IdentifierT name = impl()->NullIdentifier();
4194
  bool is_strict_reserved = Token::IsStrictReservedWord(peek());
4195
  IdentifierT variable_name = impl()->NullIdentifier();
4196 4197 4198
  if (default_export && (peek() == Token::EXTENDS || peek() == Token::LBRACE)) {
    impl()->GetDefaultStrings(&name, &variable_name);
  } else {
4199
    name = ParseIdentifier();
4200 4201 4202
    variable_name = name;
  }

4203
  ExpressionParsingScope no_expression_scope(impl());
4204 4205
  ExpressionT value = ParseClassLiteral(name, scanner()->location(),
                                        is_strict_reserved, class_token_pos);
4206
  no_expression_scope.ValidateExpression();
4207 4208
  int end_pos = position();
  return impl()->DeclareClass(variable_name, value, names, class_token_pos,
4209
                              end_pos);
4210 4211 4212 4213 4214 4215 4216
}

// 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>
4217 4218
typename ParserBase<Impl>::StatementT
ParserBase<Impl>::ParseNativeDeclaration() {
4219
  function_state_->DisableOptimization(BailoutReason::kNativeFunctionLiteral);
4220

4221
  int pos = peek_position();
4222
  Consume(Token::FUNCTION);
4223
  // Allow "eval" or "arguments" for backward compatibility.
4224
  IdentifierT name = ParseIdentifier();
4225
  Expect(Token::LPAREN);
4226 4227
  if (peek() != Token::RPAREN) {
    do {
4228
      ParseIdentifier();
4229 4230
    } while (Check(Token::COMMA));
  }
4231 4232 4233
  Expect(Token::RPAREN);
  Expect(Token::SEMICOLON);
  return impl()->DeclareNative(name, pos);
4234 4235
}

4236 4237 4238
template <typename Impl>
typename ParserBase<Impl>::StatementT
ParserBase<Impl>::ParseAsyncFunctionDeclaration(
4239
    ZonePtrList<const AstRawString>* names, bool default_export) {
4240 4241 4242 4243
  // AsyncFunctionDeclaration ::
  //   async [no LineTerminator here] function BindingIdentifier[Await]
  //       ( FormalParameters[Await] ) { AsyncFunctionBody }
  DCHECK_EQ(scanner()->current_token(), Token::ASYNC);
4244 4245 4246
  if (V8_UNLIKELY(scanner()->literal_contains_escapes())) {
    impl()->ReportUnexpectedToken(Token::ESCAPED_KEYWORD);
  }
4247
  int pos = position();
4248 4249
  DCHECK(!scanner()->HasLineTerminatorBeforeNext());
  Consume(Token::FUNCTION);
4250
  ParseFunctionFlags flags = ParseFunctionFlag::kIsAsync;
4251
  return ParseHoistableDeclaration(pos, flags, names, default_export);
4252 4253
}

4254 4255
template <typename Impl>
void ParserBase<Impl>::ParseFunctionBody(
4256 4257
    StatementListT* body, IdentifierT function_name, int pos,
    const FormalParametersT& parameters, FunctionKind kind,
4258
    FunctionSyntaxKind function_syntax_kind, FunctionBodyType body_type) {
4259
  if (IsResumableFunction(kind)) impl()->PrepareGeneratorVariables();
4260 4261 4262 4263

  DeclarationScope* function_scope = parameters.scope;
  DeclarationScope* inner_scope = function_scope;

4264 4265
  // Building the parameter initialization block declares the parameters.
  // TODO(verwaest): Rely on ArrowHeadParsingScope instead.
4266
  if (V8_UNLIKELY(!parameters.is_simple)) {
4267 4268 4269 4270 4271 4272 4273
    if (has_error()) return;
    BlockT init_block = impl()->BuildParameterInitializationBlock(parameters);
    if (IsAsyncFunction(kind) && !IsAsyncGeneratorFunction(kind)) {
      init_block = impl()->BuildRejectPromiseOnException(init_block);
    }
    body->Add(init_block);
    if (has_error()) return;
4274

4275 4276 4277
    inner_scope = NewVarblockScope();
    inner_scope->set_start_position(scanner()->location().beg_pos);
  }
4278

4279
  StatementListT inner_body(pointer_buffer());
4280

4281 4282
  {
    BlockState block_state(&scope_, inner_scope);
4283

4284 4285
    if (body_type == FunctionBodyType::kExpression) {
      ExpressionT expression = ParseAssignmentExpression();
4286

4287 4288 4289
      if (IsAsyncFunction(kind)) {
        BlockT block = factory()->NewBlock(1, true);
        impl()->RewriteAsyncFunctionBody(&inner_body, block, expression);
4290
      } else {
4291 4292 4293 4294 4295 4296 4297 4298
        inner_body.Add(
            BuildReturnStatement(expression, expression->position()));
      }
    } else {
      DCHECK(accept_IN_);
      DCHECK_EQ(FunctionBodyType::kBlock, body_type);
      // If we are parsing the source as if it is wrapped in a function, the
      // source ends without a closing brace.
4299 4300 4301
      Token::Value closing_token =
          function_syntax_kind == FunctionSyntaxKind::kWrapped ? Token::EOS
                                                               : Token::RBRACE;
4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312

      if (IsAsyncGeneratorFunction(kind)) {
        impl()->ParseAndRewriteAsyncGeneratorFunctionBody(pos, kind,
                                                          &inner_body);
      } else if (IsGeneratorFunction(kind)) {
        impl()->ParseAndRewriteGeneratorFunctionBody(pos, kind, &inner_body);
      } else if (IsAsyncFunction(kind)) {
        ParseAsyncFunctionBody(inner_scope, &inner_body);
      } else {
        ParseStatementList(&inner_body, closing_token);
      }
4313

4314 4315 4316 4317 4318 4319
      if (IsDerivedConstructor(kind)) {
        ExpressionParsingScope expression_scope(impl());
        inner_body.Add(factory()->NewReturnStatement(impl()->ThisExpression(),
                                                     kNoSourcePosition));
        expression_scope.ValidateExpression();
      }
4320
      Expect(closing_token);
4321
    }
4322
  }
4323

4324
  scope()->set_end_position(end_position());
4325

4326
  bool allow_duplicate_parameters = false;
4327

4328 4329
  CheckConflictingVarDeclarations(inner_scope);

4330 4331 4332 4333 4334
  if (V8_LIKELY(parameters.is_simple)) {
    DCHECK_EQ(inner_scope, function_scope);
    if (is_sloppy(function_scope->language_mode())) {
      impl()->InsertSloppyBlockFunctionVarBindings(function_scope);
    }
4335 4336
    allow_duplicate_parameters =
        is_sloppy(function_scope->language_mode()) && !IsConciseMethod(kind);
4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352
  } else {
    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());

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

    inner_scope->set_end_position(end_position());
    if (inner_scope->FinalizeBlockScope() != nullptr) {
      BlockT inner_block = factory()->NewBlock(true, inner_body);
      inner_body.Rewind();
      inner_body.Add(inner_block);
      inner_block->set_scope(inner_scope);
4353
      impl()->RecordBlockSourceRange(inner_block, scope()->end_position());
4354 4355 4356 4357 4358 4359
      if (!impl()->HasCheckedSyntax()) {
        const AstRawString* conflict = inner_scope->FindVariableDeclaredIn(
            function_scope, VariableMode::kLastLexicalVariableMode);
        if (conflict != nullptr) {
          impl()->ReportVarRedeclarationIn(conflict, inner_scope);
        }
4360
      }
4361
      impl()->InsertShadowingVarBindingInitializers(inner_block);
4362 4363 4364
    }
  }

4365 4366
  ValidateFormalParameters(language_mode(), parameters,
                           allow_duplicate_parameters);
4367

4368 4369 4370 4371 4372 4373 4374
  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());
  }

4375 4376
  impl()->DeclareFunctionNameVar(function_name, function_syntax_kind,
                                 function_scope);
4377 4378

  inner_body.MergeInto(body);
4379 4380
}

4381 4382 4383 4384 4385
template <typename Impl>
void ParserBase<Impl>::CheckArityRestrictions(int param_count,
                                              FunctionKind function_kind,
                                              bool has_rest,
                                              int formals_start_pos,
4386
                                              int formals_end_pos) {
4387
  if (impl()->HasCheckedSyntax()) return;
4388 4389
  if (IsGetterFunction(function_kind)) {
    if (param_count != 0) {
4390 4391 4392
      impl()->ReportMessageAt(
          Scanner::Location(formals_start_pos, formals_end_pos),
          MessageTemplate::kBadGetterArity);
4393 4394 4395
    }
  } else if (IsSetterFunction(function_kind)) {
    if (param_count != 1) {
4396 4397 4398
      impl()->ReportMessageAt(
          Scanner::Location(formals_start_pos, formals_end_pos),
          MessageTemplate::kBadSetterArity);
4399 4400
    }
    if (has_rest) {
4401 4402 4403
      impl()->ReportMessageAt(
          Scanner::Location(formals_start_pos, formals_end_pos),
          MessageTemplate::kBadSetterRestParameter);
4404
    }
4405 4406 4407
  }
}

4408 4409
template <typename Impl>
bool ParserBase<Impl>::IsNextLetKeyword() {
4410
  DCHECK_EQ(Token::LET, peek());
4411 4412 4413 4414 4415 4416
  Token::Value next_next = PeekAhead();
  switch (next_next) {
    case Token::LBRACE:
    case Token::LBRACK:
    case Token::IDENTIFIER:
    case Token::STATIC:
4417 4418 4419 4420 4421
    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.
4422 4423
    case Token::YIELD:
    case Token::AWAIT:
4424 4425
    case Token::GET:
    case Token::SET:
4426
    case Token::ASYNC:
4427
      return true;
4428 4429
    case Token::FUTURE_STRICT_RESERVED_WORD:
      return is_sloppy(language_mode());
4430 4431 4432 4433 4434
    default:
      return false;
  }
}

4435 4436 4437
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseArrowFunctionLiteral(
4438
    const FormalParametersT& formal_parameters) {
4439 4440 4441 4442 4443
  RCS_SCOPE(runtime_call_stats_,
            Impl::IsPreParser()
                ? RuntimeCallCounterId::kPreParseArrowFunctionLiteral
                : RuntimeCallCounterId::kParseArrowFunctionLiteral,
            RuntimeCallStats::kThreadSpecific);
4444 4445
  base::ElapsedTimer timer;
  if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();
4446

4447
  DCHECK_IMPLIES(!has_error(), peek() == Token::ARROW);
4448
  if (!impl()->HasCheckedSyntax() && scanner_->HasLineTerminatorBeforeNext()) {
4449 4450 4451
    // 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.
4452
    impl()->ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW);
4453
    return impl()->FailureExpression();
4454 4455
  }

4456
  int expected_property_count = 0;
4457
  int suspend_count = 0;
4458
  int function_literal_id = GetNextFunctionLiteralId();
4459

4460
  FunctionKind kind = formal_parameters.scope->function_kind();
4461
  FunctionLiteral::EagerCompileHint eager_compile_hint =
4462
      default_eager_compile_hint_;
4463
  bool can_preparse = impl()->parse_lazily() &&
4464 4465 4466 4467
                      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 =
4468
      can_preparse && impl()->AllowsLazyParsingWithoutUnresolvedVariables();
4469
  bool has_braces = true;
4470
  ProducedPreparseData* produced_preparse_data = nullptr;
4471
  StatementListT body(pointer_buffer());
4472
  {
4473
    FunctionState function_state(&function_state_, &scope_,
4474
                                 formal_parameters.scope);
4475

4476
    Consume(Token::ARROW);
4477 4478 4479

    if (peek() == Token::LBRACE) {
      // Multiple statement body
4480
      DCHECK_EQ(scope(), formal_parameters.scope);
4481

4482
      if (is_lazy_top_level_function) {
4483 4484 4485
        // 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.
4486

4487 4488 4489 4490 4491 4492 4493
        // Building the parameter initialization block declares the parameters.
        // TODO(verwaest): Rely on ArrowHeadParsingScope instead.
        if (!formal_parameters.is_simple) {
          impl()->BuildParameterInitializationBlock(formal_parameters);
          if (has_error()) return impl()->FailureExpression();
        }

4494 4495 4496
        // For arrow functions, we don't need to retrieve data about function
        // parameters.
        int dummy_num_parameters = -1;
4497
        int dummy_function_length = -1;
4498
        DCHECK_NE(kind & FunctionKind::kArrowFunction, 0);
4499
        bool did_preparse_successfully = impl()->SkipFunction(
4500
            nullptr, kind, FunctionSyntaxKind::kAnonymousExpression,
4501
            formal_parameters.scope, &dummy_num_parameters,
4502
            &dummy_function_length, &produced_preparse_data);
4503

4504
        DCHECK_NULL(produced_preparse_data);
4505 4506

        if (did_preparse_successfully) {
4507 4508 4509
          // Validate parameter names. We can do this only after preparsing the
          // function, since the function can declare itself strict.
          ValidateFormalParameters(language_mode(), formal_parameters, false);
4510 4511 4512
        } else {
          // In case we did not sucessfully preparse the function because of an
          // unidentified error we do a full reparse to return the error.
4513 4514
          // Parse again in the outer scope, since the language mode may change.
          BlockState block_state(&scope_, scope()->outer_scope());
4515
          ExpressionT expression = ParseConditionalExpression();
4516 4517 4518
          // Reparsing the head may have caused a stack overflow.
          if (has_error()) return impl()->FailureExpression();

4519 4520 4521 4522 4523 4524 4525
          DeclarationScope* function_scope = next_arrow_function_info_.scope;
          FunctionState function_state(&function_state_, &scope_,
                                       function_scope);
          Scanner::Location loc(function_scope->start_position(),
                                end_position());
          FormalParametersT parameters(function_scope);
          parameters.is_simple = function_scope->has_simple_parameters();
4526 4527 4528 4529 4530
          impl()->DeclareArrowFunctionFormalParameters(&parameters, expression,
                                                       loc);
          next_arrow_function_info_.Reset();

          Consume(Token::ARROW);
4531
          Consume(Token::LBRACE);
4532

4533
          AcceptINScope scope(this, true);
4534
          FunctionParsingScope body_parsing_scope(impl());
4535
          ParseFunctionBody(&body, impl()->NullIdentifier(), kNoSourcePosition,
4536
                            parameters, kind,
4537
                            FunctionSyntaxKind::kAnonymousExpression,
4538
                            FunctionBodyType::kBlock);
4539
          CHECK(has_error());
4540
          return impl()->FailureExpression();
4541
        }
4542
      } else {
4543
        Consume(Token::LBRACE);
4544
        AcceptINScope scope(this, true);
4545
        FunctionParsingScope body_parsing_scope(impl());
4546
        ParseFunctionBody(&body, impl()->NullIdentifier(), kNoSourcePosition,
4547
                          formal_parameters, kind,
4548
                          FunctionSyntaxKind::kAnonymousExpression,
4549
                          FunctionBodyType::kBlock);
4550 4551 4552 4553
        expected_property_count = function_state.expected_property_count();
      }
    } else {
      // Single-expression body
4554
      has_braces = false;
4555
      FunctionParsingScope body_parsing_scope(impl());
4556
      ParseFunctionBody(&body, impl()->NullIdentifier(), kNoSourcePosition,
4557
                        formal_parameters, kind,
4558
                        FunctionSyntaxKind::kAnonymousExpression,
4559
                        FunctionBodyType::kExpression);
4560 4561 4562
      expected_property_count = function_state.expected_property_count();
    }

4563
    formal_parameters.scope->set_end_position(end_position());
4564 4565 4566 4567

    // Validate strict mode.
    if (is_strict(language_mode())) {
      CheckStrictOctalLiteral(formal_parameters.scope->start_position(),
4568
                              end_position());
4569
    }
4570
    suspend_count = function_state.suspend_count();
4571 4572 4573
  }

  FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
4574
      impl()->EmptyIdentifierString(), formal_parameters.scope, body,
4575 4576
      expected_property_count, formal_parameters.num_parameters(),
      formal_parameters.function_length,
4577
      FunctionLiteral::kNoDuplicateParameters,
4578
      FunctionSyntaxKind::kAnonymousExpression, eager_compile_hint,
4579
      formal_parameters.scope->start_position(), has_braces,
4580
      function_literal_id, produced_preparse_data);
4581

4582
  function_literal->set_suspend_count(suspend_count);
4583 4584 4585
  function_literal->set_function_token_position(
      formal_parameters.scope->start_position());

4586
  impl()->RecordFunctionLiteralSourceRange(function_literal);
4587
  impl()->AddFunctionForNameInference(function_literal);
4588

4589 4590 4591 4592 4593 4594
  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";
4595 4596 4597
    logger_->FunctionEvent(event_name, flags().script_id(), ms,
                           scope->start_position(), scope->end_position(), name,
                           strlen(name));
4598 4599
  }

4600 4601 4602
  return function_literal;
}

4603 4604 4605
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseClassLiteral(
    IdentifierT name, Scanner::Location class_name_location,
4606
    bool name_is_strict_reserved, int class_token_pos) {
4607
  bool is_anonymous = impl()->IsNull(name);
4608

4609
  // All parts of a ClassDeclaration and ClassExpression are strict code.
4610
  if (!impl()->HasCheckedSyntax() && !is_anonymous) {
4611 4612 4613
    if (name_is_strict_reserved) {
      impl()->ReportMessageAt(class_name_location,
                              MessageTemplate::kUnexpectedStrictReserved);
4614
      return impl()->FailureExpression();
4615 4616 4617 4618
    }
    if (impl()->IsEvalOrArguments(name)) {
      impl()->ReportMessageAt(class_name_location,
                              MessageTemplate::kStrictEvalArguments);
4619
      return impl()->FailureExpression();
4620
    }
4621 4622
  }

4623
  ClassScope* class_scope = NewClassScope(scope(), is_anonymous);
4624
  BlockState block_state(&scope_, class_scope);
4625
  RaiseLanguageMode(LanguageMode::kStrict);
4626

4627 4628
  BlockState object_literal_scope_state(&object_literal_scope_, nullptr);

4629
  ClassInfo class_info(this);
4630
  class_info.is_anonymous = is_anonymous;
4631

4632
  scope()->set_start_position(end_position());
4633
  if (Check(Token::EXTENDS)) {
4634
    ClassScope::HeritageParsingScope heritage(class_scope);
4635
    FuncNameInferrerState fni_state(&fni_);
4636
    ExpressionParsingScope scope(impl());
4637
    class_info.extends = ParseLeftHandSideExpression();
4638
    scope.ValidateExpression();
4639 4640
  }

4641
  Expect(Token::LBRACE);
4642

4643
  const bool has_extends = !impl()->IsNull(class_info.extends);
4644 4645
  while (peek() != Token::RBRACE) {
    if (Check(Token::SEMICOLON)) continue;
4646 4647 4648 4649 4650 4651 4652 4653 4654

    // Either we're parsing a `static { }` initialization block or a property.
    if (FLAG_harmony_class_static_blocks && peek() == Token::STATIC &&
        PeekAhead() == Token::LBRACE) {
      BlockT static_block = ParseClassStaticBlock(&class_info);
      impl()->AddClassStaticBlock(static_block, &class_info);
      continue;
    }

4655
    FuncNameInferrerState fni_state(&fni_);
4656 4657 4658
    // If we haven't seen the constructor yet, it potentially is the next
    // property.
    bool is_constructor = !class_info.has_seen_constructor;
4659 4660
    ParsePropertyInfo prop_info(this);
    prop_info.position = PropertyPosition::kClassLiteral;
4661

4662 4663 4664 4665 4666 4667 4668 4669 4670
    ClassLiteralPropertyT property =
        ParseClassPropertyDefinition(&class_info, &prop_info, has_extends);

    if (has_error()) return impl()->FailureExpression();

    ClassLiteralProperty::Kind property_kind =
        ClassPropertyKindFor(prop_info.kind);
    if (!class_info.has_static_computed_names && prop_info.is_static &&
        prop_info.is_computed_name) {
4671 4672
      class_info.has_static_computed_names = true;
    }
4673
    is_constructor &= class_info.has_seen_constructor;
4674

4675 4676 4677 4678
    bool is_field = property_kind == ClassLiteralProperty::FIELD;

    if (V8_UNLIKELY(prop_info.is_private)) {
      DCHECK(!is_constructor);
4679
      class_info.requires_brand |= (!is_field && !prop_info.is_static);
4680 4681 4682
      bool is_method = property_kind == ClassLiteralProperty::METHOD;
      class_info.has_private_methods |= is_method;
      class_info.has_static_private_methods |= is_method && prop_info.is_static;
4683 4684 4685 4686 4687 4688 4689 4690 4691
      impl()->DeclarePrivateClassMember(class_scope, prop_info.name, property,
                                        property_kind, prop_info.is_static,
                                        &class_info);
      impl()->InferFunctionName();
      continue;
    }

    if (V8_UNLIKELY(is_field)) {
      DCHECK(!prop_info.is_private);
4692 4693 4694
      if (prop_info.is_computed_name) {
        class_info.computed_field_count++;
      }
4695 4696 4697 4698 4699
      impl()->DeclarePublicClassField(class_scope, property,
                                      prop_info.is_static,
                                      prop_info.is_computed_name, &class_info);
      impl()->InferFunctionName();
      continue;
4700
    }
4701 4702 4703

    impl()->DeclarePublicClassMethod(name, property, is_constructor,
                                     &class_info);
4704 4705 4706
    impl()->InferFunctionName();
  }

4707
  Expect(Token::RBRACE);
4708
  int end_pos = end_position();
4709 4710 4711 4712 4713 4714 4715
  class_scope->set_end_position(end_pos);

  VariableProxy* unresolvable = class_scope->ResolvePrivateNamesPartially();
  if (unresolvable != nullptr) {
    impl()->ReportMessageAt(Scanner::Location(unresolvable->position(),
                                              unresolvable->position() + 1),
                            MessageTemplate::kInvalidPrivateFieldResolution,
4716
                            unresolvable->raw_name());
4717 4718 4719
    return impl()->FailureExpression();
  }

4720
  if (class_info.requires_brand) {
4721 4722
    class_scope->DeclareBrandVariable(
        ast_value_factory(), IsStaticFlag::kNotStatic, kNoSourcePosition);
4723 4724
  }

4725 4726 4727 4728 4729 4730 4731
  if (class_scope->needs_home_object()) {
    class_info.home_object_variable =
        class_scope->DeclareHomeObjectVariable(ast_value_factory());
    class_info.static_home_object_variable =
        class_scope->DeclareStaticHomeObjectVariable(ast_value_factory());
  }

4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742
  bool should_save_class_variable_index =
      class_scope->should_save_class_variable_index();
  if (!is_anonymous || should_save_class_variable_index) {
    impl()->DeclareClassVariable(class_scope, name, &class_info,
                                 class_token_pos);
    if (should_save_class_variable_index) {
      class_scope->class_variable()->set_is_used();
      class_scope->class_variable()->ForceContextAllocation();
    }
  }

4743
  return impl()->RewriteClassLiteral(class_scope, name, &class_info,
4744
                                     class_token_pos, end_pos);
4745 4746
}

4747
template <typename Impl>
4748
void ParserBase<Impl>::ParseAsyncFunctionBody(Scope* scope,
4749
                                              StatementListT* body) {
4750
  BlockT block = impl()->NullBlock();
4751 4752 4753 4754 4755
  {
    StatementListT statements(pointer_buffer());
    ParseStatementList(&statements, Token::RBRACE);
    block = factory()->NewBlock(true, statements);
  }
4756
  impl()->RewriteAsyncFunctionBody(
4757
      body, block, factory()->NewUndefinedLiteral(kNoSourcePosition));
4758
  scope->set_end_position(end_position());
4759 4760 4761 4762
}

template <typename Impl>
typename ParserBase<Impl>::ExpressionT
4763
ParserBase<Impl>::ParseAsyncFunctionLiteral() {
4764 4765 4766 4767 4768 4769 4770
  // 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);
4771 4772 4773
  if (V8_UNLIKELY(scanner()->literal_contains_escapes())) {
    impl()->ReportUnexpectedToken(Token::ESCAPED_KEYWORD);
  }
4774
  int pos = position();
4775
  Consume(Token::FUNCTION);
4776
  IdentifierT name = impl()->NullIdentifier();
4777
  FunctionSyntaxKind syntax_kind = FunctionSyntaxKind::kAnonymousExpression;
4778

4779 4780 4781
  ParseFunctionFlags flags = ParseFunctionFlag::kIsAsync;
  if (Check(Token::MUL)) flags |= ParseFunctionFlag::kIsGenerator;
  const FunctionKind kind = FunctionKindFor(flags);
4782
  bool is_strict_reserved = Token::IsStrictReservedWord(peek());
4783

4784 4785 4786
  if (impl()->ParsingDynamicFunctionDeclaration()) {
    // We don't want dynamic functions to actually declare their name
    // "anonymous". We just want that name in the toString().
4787 4788 4789

    // Consuming token we did not peek yet, which could lead to a ILLEGAL token
    // in the case of a stackoverflow.
4790 4791
    Consume(Token::IDENTIFIER);
    DCHECK_IMPLIES(!has_error(),
4792 4793
                   scanner()->CurrentSymbol(ast_value_factory()) ==
                       ast_value_factory()->anonymous_string());
4794
  } else if (peek_any_identifier()) {
4795
    syntax_kind = FunctionSyntaxKind::kNamedExpression;
4796
    name = ParseIdentifier(kind);
4797
  }
4798
  FunctionLiteralT result = impl()->ParseFunctionLiteral(
4799 4800 4801
      name, scanner()->location(),
      is_strict_reserved ? kFunctionNameIsStrictReserved
                         : kFunctionNameValidityUnknown,
4802
      kind, pos, syntax_kind, language_mode(), nullptr);
4803 4804
  if (impl()->IsNull(result)) return impl()->FailureExpression();
  return result;
4805 4806
}

4807 4808
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral(
4809
    ExpressionT tag, int start, bool tagged) {
4810 4811 4812 4813 4814 4815 4816 4817 4818 4819
  // 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.
4820
  DCHECK(peek() == Token::TEMPLATE_SPAN || peek() == Token::TEMPLATE_TAIL);
4821

4822 4823 4824 4825 4826 4827
  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);
  }

4828
  bool forbid_illegal_escapes = !tagged;
4829

4830 4831 4832 4833 4834 4835
  // 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();
4836
    typename Impl::TemplateLiteralState ts = impl()->OpenTemplateLiteral(pos);
4837
    bool is_valid = CheckTemplateEscapes(forbid_illegal_escapes);
4838
    impl()->AddTemplateSpan(&ts, is_valid, true);
4839
    return impl()->CloseTemplateLiteral(&ts, start, tag);
4840 4841 4842 4843
  }

  Consume(Token::TEMPLATE_SPAN);
  int pos = position();
4844
  typename Impl::TemplateLiteralState ts = impl()->OpenTemplateLiteral(pos);
4845
  bool is_valid = CheckTemplateEscapes(forbid_illegal_escapes);
4846
  impl()->AddTemplateSpan(&ts, is_valid, false);
4847 4848 4849 4850 4851 4852 4853 4854 4855 4856
  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();

    int expr_pos = peek_position();
4857 4858
    AcceptINScope scope(this, true);
    ExpressionT expression = ParseExpressionCoverGrammar();
4859
    impl()->AddTemplateExpression(&ts, expression);
4860 4861

    if (peek() != Token::RBRACE) {
4862 4863
      impl()->ReportMessageAt(Scanner::Location(expr_pos, peek_position()),
                              MessageTemplate::kUnterminatedTemplateExpr);
4864
      return impl()->FailureExpression();
4865 4866 4867 4868 4869 4870 4871 4872
    }

    // 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();

4873
    bool is_valid = CheckTemplateEscapes(forbid_illegal_escapes);
4874
    impl()->AddTemplateSpan(&ts, is_valid, next == Token::TEMPLATE_TAIL);
4875 4876
  } while (next == Token::TEMPLATE_SPAN);

4877
  DCHECK_IMPLIES(!has_error(), next == Token::TEMPLATE_TAIL);
4878
  // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral.
4879
  return impl()->CloseTemplateLiteral(&ts, start, tag);
4880 4881
}

4882 4883
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
4884 4885
ParserBase<Impl>::RewriteInvalidReferenceExpression(ExpressionT expression,
                                                    int beg_pos, int end_pos,
4886 4887
                                                    MessageTemplate message,
                                                    bool early_error) {
4888
  DCHECK(!IsValidReferenceExpression(expression));
4889 4890 4891
  if (impl()->IsIdentifier(expression)) {
    DCHECK(is_strict(language_mode()));
    DCHECK(impl()->IsEvalOrArguments(impl()->AsIdentifier(expression)));
4892

4893
    ReportMessageAt(Scanner::Location(beg_pos, end_pos),
4894
                    MessageTemplate::kStrictEvalArguments);
4895
    return impl()->FailureExpression();
4896
  }
4897 4898
  if (expression->IsCall() && !expression->AsCall()->is_tagged_template() &&
      !early_error) {
4899 4900 4901
    expression_scope()->RecordPatternError(
        Scanner::Location(beg_pos, end_pos),
        MessageTemplate::kInvalidDestructuringTarget);
4902
    // If it is a call, make it a runtime error for legacy web compatibility.
4903
    // Bug: https://bugs.chromium.org/p/v8/issues/detail?id=4480
4904
    // Rewrite `expr' to `expr[throw ReferenceError]'.
4905 4906 4907 4908
    impl()->CountUsage(
        is_strict(language_mode())
            ? v8::Isolate::kAssigmentExpressionLHSIsCallInStrict
            : v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy);
4909
    ExpressionT error = impl()->NewThrowReferenceError(message, beg_pos);
4910
    return factory()->NewProperty(expression, error, beg_pos);
4911
  }
4912 4913 4914
  // Tagged templates and other modern language features (which pass early_error
  // = true) are exempt from the web compatibility hack. Throw a regular early
  // error.
4915
  ReportMessageAt(Scanner::Location(beg_pos, end_pos), message);
4916
  return impl()->FailureExpression();
4917 4918
}

4919
template <typename Impl>
4920 4921 4922 4923
void ParserBase<Impl>::ClassifyParameter(IdentifierT parameter, int begin,
                                         int end) {
  if (impl()->IsEvalOrArguments(parameter)) {
    expression_scope()->RecordStrictModeParameterError(
4924 4925 4926 4927 4928
        Scanner::Location(begin, end), MessageTemplate::kStrictEvalArguments);
  }
}

template <typename Impl>
4929 4930 4931 4932 4933 4934 4935 4936 4937
void ParserBase<Impl>::ClassifyArrowParameter(
    AccumulationScope* accumulation_scope, int position,
    ExpressionT parameter) {
  accumulation_scope->Accumulate();
  if (parameter->is_parenthesized() ||
      !(impl()->IsIdentifier(parameter) || parameter->IsPattern() ||
        parameter->IsAssignment())) {
    expression_scope()->RecordDeclarationError(
        Scanner::Location(position, end_position()),
4938
        MessageTemplate::kInvalidDestructuringTarget);
4939 4940 4941
  } else if (impl()->IsIdentifier(parameter)) {
    ClassifyParameter(impl()->AsIdentifier(parameter), position,
                      end_position());
4942
  } else {
4943
    expression_scope()->RecordNonSimpleParameter();
4944 4945 4946
  }
}

4947 4948
template <typename Impl>
bool ParserBase<Impl>::IsValidReferenceExpression(ExpressionT expression) {
4949 4950 4951 4952 4953 4954 4955
  return IsAssignableIdentifier(expression) || expression->IsProperty();
}

template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParsePossibleDestructuringSubPattern(
    AccumulationScope* scope) {
4956
  if (scope) scope->Accumulate();
4957 4958
  int begin = peek_position();
  ExpressionT result = ParseAssignmentExpressionCoverGrammar();
4959

4960
  if (IsValidReferenceExpression(result)) {
4961 4962 4963 4964
    // Parenthesized identifiers and property references are allowed as part of
    // a larger assignment pattern, even though parenthesized patterns
    // themselves are not allowed, e.g., "[(x)] = []". Only accumulate
    // assignment pattern errors if the parsed expression is more complex.
4965
    if (impl()->IsIdentifier(result)) {
4966 4967 4968 4969 4970
      if (result->is_parenthesized()) {
        expression_scope()->RecordDeclarationError(
            Scanner::Location(begin, end_position()),
            MessageTemplate::kInvalidDestructuringTarget);
      }
4971 4972
      IdentifierT identifier = impl()->AsIdentifier(result);
      ClassifyParameter(identifier, begin, end_position());
4973 4974 4975 4976 4977 4978
    } else {
      DCHECK(result->IsProperty());
      expression_scope()->RecordDeclarationError(
          Scanner::Location(begin, end_position()),
          MessageTemplate::kInvalidPropertyBindingPattern);
      if (scope != nullptr) scope->ValidateExpression();
4979
    }
4980 4981
  } else if (result->is_parenthesized() ||
             (!result->IsPattern() && !result->IsAssignment())) {
4982
    expression_scope()->RecordPatternError(
4983
        Scanner::Location(begin, end_position()),
4984
        MessageTemplate::kInvalidDestructuringTarget);
4985
  }
4986 4987

  return result;
4988 4989
}

4990
template <typename Impl>
4991
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseV8Intrinsic() {
4992 4993 4994 4995
  // CallRuntime ::
  //   '%' Identifier Arguments

  int pos = peek_position();
4996
  Consume(Token::MOD);
4997
  // Allow "eval" or "arguments" for backward compatibility.
4998
  IdentifierT name = ParseIdentifier();
4999 5000
  if (peek() != Token::LPAREN) {
    impl()->ReportUnexpectedToken(peek());
5001
    return impl()->FailureExpression();
5002
  }
5003
  bool has_spread;
5004
  ExpressionListT args(pointer_buffer());
5005
  ParseArguments(&args, &has_spread);
5006

5007 5008
  if (has_spread) {
    ReportMessageAt(Scanner::Location(pos, position()),
5009
                    MessageTemplate::kIntrinsicWithSpread);
5010
    return impl()->FailureExpression();
5011
  }
5012

5013
  return impl()->NewV8Intrinsic(name, args, pos);
5014 5015
}

5016
template <typename Impl>
5017 5018
void ParserBase<Impl>::ParseStatementList(StatementListT* body,
                                          Token::Value end_token) {
5019 5020
  // StatementList ::
  //   (StatementListItem)* <end_token>
5021
  DCHECK_NOT_NULL(body);
5022

5023 5024
  while (peek() == Token::STRING) {
    bool use_strict = false;
5025
#if V8_ENABLE_WEBASSEMBLY
5026
    bool use_asm = false;
5027
#endif  // V8_ENABLE_WEBASSEMBLY
5028

5029
    Scanner::Location token_loc = scanner()->peek_location();
5030

5031
    if (scanner()->NextLiteralExactlyEquals("use strict")) {
5032
      use_strict = true;
5033
#if V8_ENABLE_WEBASSEMBLY
5034
    } else if (scanner()->NextLiteralExactlyEquals("use asm")) {
5035
      use_asm = true;
5036
#endif  // V8_ENABLE_WEBASSEMBLY
5037 5038 5039
    }

    StatementT stat = ParseStatementListItem();
5040
    if (impl()->IsNull(stat)) return;
5041

5042
    body->Add(stat);
5043 5044 5045 5046

    if (!impl()->IsStringLiteral(stat)) break;

    if (use_strict) {
5047 5048 5049 5050 5051 5052 5053 5054 5055
      // Directive "use strict" (ES5 14.1).
      RaiseLanguageMode(LanguageMode::kStrict);
      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");
5056
        return;
5057
      }
5058
#if V8_ENABLE_WEBASSEMBLY
5059
    } else if (use_asm) {
5060 5061
      // Directive "use asm".
      impl()->SetAsmModule();
5062
#endif  // V8_ENABLE_WEBASSEMBLY
5063
    } else {
5064 5065 5066
      // Possibly an unknown directive.
      // Should not change mode, but will increment usage counters
      // as appropriate. Ditto usages below.
5067
      RaiseLanguageMode(LanguageMode::kSloppy);
5068
    }
5069
  }
5070

5071 5072
  while (peek() != end_token) {
    StatementT stat = ParseStatementListItem();
5073
    if (impl()->IsNull(stat)) return;
5074
    if (stat->IsEmptyStatement()) continue;
5075
    body->Add(stat);
5076 5077 5078 5079
  }
}

template <typename Impl>
5080 5081
typename ParserBase<Impl>::StatementT
ParserBase<Impl>::ParseStatementListItem() {
5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100
  // 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:
5101
      return ParseHoistableDeclaration(nullptr, false);
5102 5103
    case Token::CLASS:
      Consume(Token::CLASS);
5104
      return ParseClassDeclaration(nullptr, false);
5105 5106
    case Token::VAR:
    case Token::CONST:
5107
      return ParseVariableStatement(kStatementListItem, nullptr);
5108 5109
    case Token::LET:
      if (IsNextLetKeyword()) {
5110
        return ParseVariableStatement(kStatementListItem, nullptr);
5111 5112 5113
      }
      break;
    case Token::ASYNC:
5114
      if (PeekAhead() == Token::FUNCTION &&
5115
          !scanner()->HasLineTerminatorAfterNext()) {
5116
        Consume(Token::ASYNC);
5117
        return ParseAsyncFunctionDeclaration(nullptr, false);
5118
      }
5119
      break;
5120 5121 5122
    default:
      break;
  }
5123
  return ParseStatement(nullptr, nullptr, kAllowLabelledFunctionStatement);
5124 5125 5126 5127
}

template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseStatement(
5128
    ZonePtrList<const AstRawString>* labels,
5129
    ZonePtrList<const AstRawString>* own_labels,
5130
    AllowLabelledFunctionStatement allow_function) {
5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147
  // Statement ::
  //   Block
  //   VariableStatement
  //   EmptyStatement
  //   ExpressionStatement
  //   IfStatement
  //   IterationStatement
  //   ContinueStatement
  //   BreakStatement
  //   ReturnStatement
  //   WithStatement
  //   LabelledStatement
  //   SwitchStatement
  //   ThrowStatement
  //   TryStatement
  //   DebuggerStatement

5148 5149 5150
  // {own_labels} is always a subset of {labels}.
  DCHECK_IMPLIES(labels == nullptr, own_labels == nullptr);

5151 5152 5153 5154 5155 5156 5157 5158
  // 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:
5159
      return ParseBlock(labels);
5160 5161
    case Token::SEMICOLON:
      Next();
5162
      return factory()->EmptyStatement();
5163
    case Token::IF:
5164
      return ParseIfStatement(labels);
5165
    case Token::DO:
5166
      return ParseDoWhileStatement(labels, own_labels);
5167
    case Token::WHILE:
5168
      return ParseWhileStatement(labels, own_labels);
5169
    case Token::FOR:
5170
      if (V8_UNLIKELY(is_await_allowed() && PeekAhead() == Token::AWAIT)) {
5171
        return ParseForAwaitStatement(labels, own_labels);
5172
      }
5173
      return ParseForStatement(labels, own_labels);
5174
    case Token::CONTINUE:
5175
      return ParseContinueStatement();
5176
    case Token::BREAK:
5177
      return ParseBreakStatement(labels);
5178
    case Token::RETURN:
5179
      return ParseReturnStatement();
5180
    case Token::THROW:
5181
      return ParseThrowStatement();
5182
    case Token::TRY: {
5183 5184 5185 5186 5187
      // 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.
5188
      if (labels == nullptr) return ParseTryStatement();
5189
      StatementListT statements(pointer_buffer());
5190 5191 5192
      BlockT result = factory()->NewBlock(false, true);
      Target target(this, result, labels, nullptr,
                    Target::TARGET_FOR_NAMED_ONLY);
5193
      StatementT statement = ParseTryStatement();
5194 5195
      statements.Add(statement);
      result->InitializeStatements(statements, zone());
5196
      return result;
5197 5198
    }
    case Token::WITH:
5199
      return ParseWithStatement(labels);
5200
    case Token::SWITCH:
5201
      return ParseSwitchStatement(labels);
5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213
    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);
      return impl()->NullStatement();
    case Token::DEBUGGER:
5214
      return ParseDebuggerStatement();
5215
    case Token::VAR:
5216
      return ParseVariableStatement(kStatement, nullptr);
5217
    case Token::ASYNC:
5218 5219
      if (!impl()->HasCheckedSyntax() &&
          !scanner()->HasLineTerminatorAfterNext() &&
5220 5221 5222 5223 5224 5225
          PeekAhead() == Token::FUNCTION) {
        impl()->ReportMessageAt(
            scanner()->peek_location(),
            MessageTemplate::kAsyncFunctionInSingleStatementContext);
        return impl()->NullStatement();
      }
5226
      V8_FALLTHROUGH;
5227
    default:
5228
      return ParseExpressionOrLabelledStatement(labels, own_labels,
5229
                                                allow_function);
5230 5231 5232
  }
}

5233 5234
template <typename Impl>
typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseBlock(
5235
    ZonePtrList<const AstRawString>* labels, Scope* block_scope) {
5236 5237 5238
  // Block ::
  //   '{' StatementList '}'

5239
  // Parse the statements and collect escaping labels.
5240
  BlockT body = factory()->NewBlock(false, labels != nullptr);
5241
  StatementListT statements(pointer_buffer());
5242

5243 5244
  CheckStackOverflow();

5245
  {
5246
    BlockState block_state(&scope_, block_scope);
5247
    scope()->set_start_position(peek_position());
5248
    Target target(this, body, labels, nullptr, Target::TARGET_FOR_NAMED_ONLY);
5249

5250 5251
    Expect(Token::LBRACE);

5252
    while (peek() != Token::RBRACE) {
5253
      StatementT stat = ParseStatementListItem();
5254
      if (impl()->IsNull(stat)) return body;
5255
      if (stat->IsEmptyStatement()) continue;
5256
      statements.Add(stat);
5257 5258
    }

5259
    Expect(Token::RBRACE);
5260

5261 5262
    int end_pos = end_position();
    scope()->set_end_position(end_pos);
5263

5264
    impl()->RecordBlockSourceRange(body, end_pos);
5265
    body->set_scope(scope()->FinalizeBlockScope());
5266
  }
5267 5268

  body->InitializeStatements(statements, zone_);
5269 5270 5271
  return body;
}

5272 5273 5274 5275 5276 5277
template <typename Impl>
typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseBlock(
    ZonePtrList<const AstRawString>* labels) {
  return ParseBlock(labels, NewScope(BLOCK_SCOPE));
}

5278 5279
template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseScopedStatement(
5280
    ZonePtrList<const AstRawString>* labels) {
5281
  if (is_strict(language_mode()) || peek() != Token::FUNCTION) {
5282
    return ParseStatement(labels, nullptr);
5283 5284 5285
  } else {
    // Make a block around the statement for a lexical binding
    // is introduced by a FunctionDeclaration.
5286 5287
    BlockState block_state(zone(), &scope_);
    scope()->set_start_position(scanner()->location().beg_pos);
5288
    BlockT block = factory()->NewBlock(1, false);
5289
    StatementT body = ParseFunctionDeclaration();
5290
    block->statements()->Add(body, zone());
5291
    scope()->set_end_position(end_position());
5292
    block->set_scope(scope()->FinalizeBlockScope());
5293 5294 5295 5296 5297 5298 5299
    return block;
  }
}

template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseVariableStatement(
    VariableDeclarationContext var_context,
5300
    ZonePtrList<const AstRawString>* names) {
5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316
  // 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;
5317
  ParseVariableDeclarations(var_context, &parsing_result, names);
5318
  ExpectSemicolon();
5319
  return impl()->BuildInitializationBlock(&parsing_result);
5320 5321 5322
}

template <typename Impl>
5323 5324
typename ParserBase<Impl>::StatementT
ParserBase<Impl>::ParseDebuggerStatement() {
5325 5326 5327 5328 5329 5330 5331
  // 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();
5332
  Consume(Token::DEBUGGER);
5333
  ExpectSemicolon();
5334 5335 5336
  return factory()->NewDebuggerStatement(pos);
}

5337 5338 5339
template <typename Impl>
typename ParserBase<Impl>::StatementT
ParserBase<Impl>::ParseExpressionOrLabelledStatement(
5340
    ZonePtrList<const AstRawString>* labels,
5341
    ZonePtrList<const AstRawString>* own_labels,
5342
    AllowLabelledFunctionStatement allow_function) {
5343 5344 5345 5346 5347
  // ExpressionStatement | LabelledStatement ::
  //   Expression ';'
  //   Identifier ':' Statement
  //
  // ExpressionStatement[Yield] :
5348
  //   [lookahead notin {{, function, class, let [}] Expression[In, ?Yield] ;
5349 5350 5351 5352 5353 5354 5355 5356 5357 5358

  int pos = peek_position();

  switch (peek()) {
    case Token::FUNCTION:
    case Token::LBRACE:
      UNREACHABLE();  // Always handled by the callers.
    case Token::CLASS:
      ReportUnexpectedToken(Next());
      return impl()->NullStatement();
5359 5360 5361 5362
    case Token::LET: {
      Token::Value next_next = PeekAhead();
      // "let" followed by either "[", "{" or an identifier means a lexical
      // declaration, which should not appear here.
5363 5364 5365
      // 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) ||
5366
           scanner_->HasLineTerminatorAfterNext())) {
5367 5368
        break;
      }
5369 5370 5371
      impl()->ReportMessageAt(scanner()->peek_location(),
                              MessageTemplate::kUnexpectedLexicalDeclaration);
      return impl()->NullStatement();
5372
    }
5373 5374 5375 5376 5377
    default:
      break;
  }

  bool starts_with_identifier = peek_any_identifier();
5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407

  ExpressionT expr;
  {
    // Effectively inlines ParseExpression, so potential labels can be extracted
    // from expression_scope.
    ExpressionParsingScope expression_scope(impl());
    AcceptINScope scope(this, true);
    expr = ParseExpressionCoverGrammar();
    expression_scope.ValidateExpression();

    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.
      DCHECK_EQ(expression_scope.variable_list()->length(), 1);
      VariableProxy* label = expression_scope.variable_list()->at(0).first;
      impl()->DeclareLabel(&labels, &own_labels, label->raw_name());

      // Remove the "ghost" variable that turned out to be a label from the top
      // scope. This way, we don't try to resolve it during the scope
      // processing.
      this->scope()->DeleteUnresolved(label);

      Consume(Token::COLON);
      // ES#sec-labelled-function-declarations Labelled Function Declarations
      if (peek() == Token::FUNCTION && is_sloppy(language_mode()) &&
          allow_function == kAllowLabelledFunctionStatement) {
        return ParseFunctionDeclaration();
      }
      return ParseStatement(labels, own_labels, allow_function);
5408 5409 5410 5411 5412 5413 5414
    }
  }

  // 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 &&
5415
      !scanner()->HasLineTerminatorBeforeNext() && impl()->IsNative(expr) &&
5416
      !scanner()->literal_contains_escapes()) {
5417
    return ParseNativeDeclaration();
5418 5419 5420
  }

  // Parsed expression statement, followed by semicolon.
5421
  ExpectSemicolon();
5422
  if (expr->IsFailureExpression()) return impl()->NullStatement();
5423 5424 5425 5426 5427
  return factory()->NewExpressionStatement(expr, pos);
}

template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseIfStatement(
5428
    ZonePtrList<const AstRawString>* labels) {
5429 5430 5431 5432
  // IfStatement ::
  //   'if' '(' Expression ')' Statement ('else' Statement)?

  int pos = peek_position();
5433
  Consume(Token::IF);
5434 5435 5436
  Expect(Token::LPAREN);
  ExpressionT condition = ParseExpression();
  Expect(Token::RPAREN);
5437 5438 5439 5440 5441

  SourceRange then_range, else_range;
  StatementT then_statement = impl()->NullStatement();
  {
    SourceRangeScope range_scope(scanner(), &then_range);
5442 5443 5444 5445 5446
    // Make a copy of {labels} to avoid conflicts with any
    // labels that may be applied to the else clause below.
    auto labels_copy =
        labels == nullptr
            ? labels
5447 5448
            : zone()->template New<ZonePtrList<const AstRawString>>(*labels,
                                                                    zone());
5449
    then_statement = ParseScopedStatement(labels_copy);
5450 5451
  }

5452 5453
  StatementT else_statement = impl()->NullStatement();
  if (Check(Token::ELSE)) {
5454
    else_statement = ParseScopedStatement(labels);
5455
    else_range = SourceRange::ContinuationOf(then_range, end_position());
5456
  } else {
5457
    else_statement = factory()->EmptyStatement();
5458
  }
5459 5460 5461 5462
  StatementT stmt =
      factory()->NewIfStatement(condition, then_statement, else_statement, pos);
  impl()->RecordIfStatementSourceRange(stmt, then_range, else_range);
  return stmt;
5463 5464 5465
}

template <typename Impl>
5466 5467
typename ParserBase<Impl>::StatementT
ParserBase<Impl>::ParseContinueStatement() {
5468 5469 5470 5471
  // ContinueStatement ::
  //   'continue' Identifier? ';'

  int pos = peek_position();
5472
  Consume(Token::CONTINUE);
5473
  IdentifierT label = impl()->NullIdentifier();
5474
  Token::Value tok = peek();
5475 5476
  if (!scanner()->HasLineTerminatorBeforeNext() &&
      !Token::IsAutoSemicolon(tok)) {
5477
    // ECMA allows "eval" or "arguments" as labels even in strict mode.
5478
    label = ParseIdentifier();
5479
  }
5480
  IterationStatementT target = LookupContinueTarget(label);
5481
  if (impl()->IsNull(target)) {
5482
    // Illegal continue statement.
5483
    MessageTemplate message = MessageTemplate::kIllegalContinue;
5484
    BreakableStatementT breakable_target = LookupBreakTarget(label);
5485
    if (impl()->IsNull(label)) {
5486
      message = MessageTemplate::kNoIterationStatement;
5487
    } else if (impl()->IsNull(breakable_target)) {
5488 5489 5490 5491 5492
      message = MessageTemplate::kUnknownLabel;
    }
    ReportMessage(message, label);
    return impl()->NullStatement();
  }
5493
  ExpectSemicolon();
5494
  StatementT stmt = factory()->NewContinueStatement(target, pos);
5495
  impl()->RecordJumpStatementSourceRange(stmt, end_position());
5496
  return stmt;
5497 5498 5499 5500
}

template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseBreakStatement(
5501
    ZonePtrList<const AstRawString>* labels) {
5502 5503 5504 5505
  // BreakStatement ::
  //   'break' Identifier? ';'

  int pos = peek_position();
5506
  Consume(Token::BREAK);
5507
  IdentifierT label = impl()->NullIdentifier();
5508
  Token::Value tok = peek();
5509 5510
  if (!scanner()->HasLineTerminatorBeforeNext() &&
      !Token::IsAutoSemicolon(tok)) {
5511
    // ECMA allows "eval" or "arguments" as labels even in strict mode.
5512
    label = ParseIdentifier();
5513 5514 5515
  }
  // Parse labeled break statements that target themselves into
  // empty statements, e.g. 'l1: l2: l3: break l2;'
5516 5517
  if (!impl()->IsNull(label) &&
      impl()->ContainsLabel(labels, impl()->GetRawNameFromIdentifier(label))) {
5518
    ExpectSemicolon();
5519
    return factory()->EmptyStatement();
5520
  }
5521
  BreakableStatementT target = LookupBreakTarget(label);
5522
  if (impl()->IsNull(target)) {
5523
    // Illegal break statement.
5524
    MessageTemplate message = MessageTemplate::kIllegalBreak;
5525
    if (!impl()->IsNull(label)) {
5526 5527 5528 5529 5530
      message = MessageTemplate::kUnknownLabel;
    }
    ReportMessage(message, label);
    return impl()->NullStatement();
  }
5531
  ExpectSemicolon();
5532
  StatementT stmt = factory()->NewBreakStatement(target, pos);
5533
  impl()->RecordJumpStatementSourceRange(stmt, end_position());
5534
  return stmt;
5535 5536 5537
}

template <typename Impl>
5538
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseReturnStatement() {
5539 5540 5541 5542 5543 5544
  // 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).
5545
  Consume(Token::RETURN);
5546 5547
  Scanner::Location loc = scanner()->location();

5548 5549 5550 5551 5552 5553 5554 5555 5556 5557
  switch (GetDeclarationScope()->scope_type()) {
    case SCRIPT_SCOPE:
    case EVAL_SCOPE:
    case MODULE_SCOPE:
      impl()->ReportMessageAt(loc, MessageTemplate::kIllegalReturn);
      return impl()->NullStatement();
    default:
      break;
  }

5558
  Token::Value tok = peek();
5559
  ExpressionT return_value = impl()->NullExpression();
5560
  if (scanner()->HasLineTerminatorBeforeNext() || Token::IsAutoSemicolon(tok)) {
5561
    if (IsDerivedConstructor(function_state_->kind())) {
5562 5563 5564
      ExpressionParsingScope expression_scope(impl());
      return_value = impl()->ThisExpression();
      expression_scope.ValidateExpression();
5565 5566
    }
  } else {
5567
    return_value = ParseExpression();
5568
  }
5569
  ExpectSemicolon();
5570

5571
  return_value = impl()->RewriteReturn(return_value, loc.beg_pos);
5572
  int continuation_pos = end_position();
5573 5574
  StatementT stmt =
      BuildReturnStatement(return_value, loc.beg_pos, continuation_pos);
5575
  impl()->RecordJumpStatementSourceRange(stmt, end_position());
5576
  return stmt;
5577 5578 5579 5580
}

template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseWithStatement(
5581
    ZonePtrList<const AstRawString>* labels) {
5582 5583 5584
  // WithStatement ::
  //   'with' '(' Expression ')' Statement

5585
  Consume(Token::WITH);
5586 5587 5588 5589 5590 5591 5592
  int pos = position();

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

5593 5594 5595
  Expect(Token::LPAREN);
  ExpressionT expr = ParseExpression();
  Expect(Token::RPAREN);
5596 5597 5598 5599

  Scope* with_scope = NewScope(WITH_SCOPE);
  StatementT body = impl()->NullStatement();
  {
5600
    BlockState block_state(&scope_, with_scope);
5601
    with_scope->set_start_position(scanner()->peek_location().beg_pos);
5602
    body = ParseStatement(labels, nullptr);
5603
    with_scope->set_end_position(end_position());
5604 5605 5606 5607
  }
  return factory()->NewWithStatement(with_scope, expr, body, pos);
}

5608 5609
template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseDoWhileStatement(
5610
    ZonePtrList<const AstRawString>* labels,
5611
    ZonePtrList<const AstRawString>* own_labels) {
5612 5613
  // DoStatement ::
  //   'do' Statement 'while' '(' Expression ')' ';'
5614 5615
  typename FunctionState::LoopScope loop_scope(function_state_);

5616 5617
  auto loop = factory()->NewDoWhileStatement(peek_position());
  Target target(this, loop, labels, own_labels, Target::TARGET_FOR_ANONYMOUS);
5618

5619 5620 5621
  SourceRange body_range;
  StatementT body = impl()->NullStatement();

5622
  Consume(Token::DO);
5623 5624

  CheckStackOverflow();
5625 5626
  {
    SourceRangeScope range_scope(scanner(), &body_range);
5627
    body = ParseStatement(nullptr, nullptr);
5628
  }
5629 5630
  Expect(Token::WHILE);
  Expect(Token::LPAREN);
5631

5632 5633
  ExpressionT cond = ParseExpression();
  Expect(Token::RPAREN);
5634 5635 5636 5637 5638 5639 5640

  // 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);

5641 5642 5643
  loop->Initialize(cond, body);
  impl()->RecordIterationStatementSourceRange(loop, body_range);

5644 5645 5646 5647 5648
  return loop;
}

template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseWhileStatement(
5649
    ZonePtrList<const AstRawString>* labels,
5650
    ZonePtrList<const AstRawString>* own_labels) {
5651 5652
  // WhileStatement ::
  //   'while' '(' Expression ')' Statement
5653
  typename FunctionState::LoopScope loop_scope(function_state_);
5654

5655 5656
  auto loop = factory()->NewWhileStatement(peek_position());
  Target target(this, loop, labels, own_labels, Target::TARGET_FOR_ANONYMOUS);
5657

5658 5659 5660
  SourceRange body_range;
  StatementT body = impl()->NullStatement();

5661
  Consume(Token::WHILE);
5662 5663 5664
  Expect(Token::LPAREN);
  ExpressionT cond = ParseExpression();
  Expect(Token::RPAREN);
5665 5666
  {
    SourceRangeScope range_scope(scanner(), &body_range);
5667
    body = ParseStatement(nullptr, nullptr);
5668
  }
5669

5670 5671 5672
  loop->Initialize(cond, body);
  impl()->RecordIterationStatementSourceRange(loop, body_range);

5673 5674 5675 5676
  return loop;
}

template <typename Impl>
5677
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseThrowStatement() {
5678 5679 5680
  // ThrowStatement ::
  //   'throw' Expression ';'

5681
  Consume(Token::THROW);
5682
  int pos = position();
5683
  if (scanner()->HasLineTerminatorBeforeNext()) {
5684 5685 5686
    ReportMessage(MessageTemplate::kNewlineAfterThrow);
    return impl()->NullStatement();
  }
5687 5688
  ExpressionT exception = ParseExpression();
  ExpectSemicolon();
5689

5690
  StatementT stmt = impl()->NewThrowStatement(exception, pos);
5691
  impl()->RecordThrowSourceRange(stmt, end_position());
5692 5693

  return stmt;
5694 5695
}

5696 5697
template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseSwitchStatement(
5698
    ZonePtrList<const AstRawString>* labels) {
5699 5700 5701 5702 5703 5704 5705
  // SwitchStatement ::
  //   'switch' '(' Expression ')' '{' CaseClause* '}'
  // CaseClause ::
  //   'case' Expression ':' StatementList
  //   'default' ':' StatementList
  int switch_pos = peek_position();

5706
  Consume(Token::SWITCH);
5707 5708 5709
  Expect(Token::LPAREN);
  ExpressionT tag = ParseExpression();
  Expect(Token::RPAREN);
5710

5711
  auto switch_statement = factory()->NewSwitchStatement(tag, switch_pos);
5712 5713

  {
5714
    BlockState cases_block_state(zone(), &scope_);
5715
    scope()->set_start_position(switch_pos);
5716
    scope()->SetNonlinear();
5717 5718
    Target target(this, switch_statement, labels, nullptr,
                  Target::TARGET_FOR_ANONYMOUS);
5719 5720

    bool default_seen = false;
5721
    Expect(Token::LBRACE);
5722 5723
    while (peek() != Token::RBRACE) {
      // An empty label indicates the default case.
5724
      ExpressionT label = impl()->NullExpression();
5725
      StatementListT statements(pointer_buffer());
5726
      SourceRange clause_range;
5727 5728 5729
      {
        SourceRangeScope range_scope(scanner(), &clause_range);
        if (Check(Token::CASE)) {
5730
          label = ParseExpression();
5731
        } else {
5732
          Expect(Token::DEFAULT);
5733 5734 5735 5736 5737 5738
          if (default_seen) {
            ReportMessage(MessageTemplate::kMultipleDefaultsInSwitch);
            return impl()->NullStatement();
          }
          default_seen = true;
        }
5739
        Expect(Token::COLON);
5740 5741
        while (peek() != Token::CASE && peek() != Token::DEFAULT &&
               peek() != Token::RBRACE) {
5742
          StatementT stat = ParseStatementListItem();
5743
          if (impl()->IsNull(stat)) return stat;
5744
          if (stat->IsEmptyStatement()) continue;
5745
          statements.Add(stat);
5746 5747
        }
      }
5748
      auto clause = factory()->NewCaseClause(label, statements);
5749
      impl()->RecordCaseClauseSourceRange(clause, clause_range);
5750
      switch_statement->cases()->Add(clause, zone());
5751
    }
5752
    Expect(Token::RBRACE);
5753

5754 5755 5756
    int end_pos = end_position();
    scope()->set_end_position(end_pos);
    impl()->RecordSwitchStatementSourceRange(switch_statement, end_pos);
5757 5758 5759 5760 5761
    Scope* switch_scope = scope()->FinalizeBlockScope();
    if (switch_scope != nullptr) {
      return impl()->RewriteSwitchStatement(switch_statement, switch_scope);
    }
    return switch_statement;
5762 5763 5764
  }
}

5765
template <typename Impl>
5766
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseTryStatement() {
5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777
  // TryStatement ::
  //   'try' Block Catch
  //   'try' Block Finally
  //   'try' Block Catch Finally
  //
  // Catch ::
  //   'catch' '(' Identifier ')' Block
  //
  // Finally ::
  //   'finally' Block

5778
  Consume(Token::TRY);
5779 5780
  int pos = position();

5781
  BlockT try_block = ParseBlock(nullptr);
5782 5783 5784 5785 5786 5787 5788 5789

  CatchInfo catch_info(this);

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

5790 5791
  SourceRange catch_range, finally_range;

5792
  BlockT catch_block = impl()->NullBlock();
5793 5794 5795
  {
    SourceRangeScope catch_range_scope(scanner(), &catch_range);
    if (Check(Token::CATCH)) {
5796
      bool has_binding;
5797
      has_binding = Check(Token::LPAREN);
5798

5799 5800 5801
      if (has_binding) {
        catch_info.scope = NewScope(CATCH_SCOPE);
        catch_info.scope->set_start_position(scanner()->location().beg_pos);
5802

5803
        {
5804
          BlockState catch_block_state(&scope_, catch_info.scope);
5805
          StatementListT catch_statements(pointer_buffer());
5806 5807 5808 5809 5810

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

            if (peek_any_identifier()) {
5814 5815 5816 5817
              IdentifierT identifier = ParseNonRestrictedIdentifier();
              RETURN_IF_PARSE_ERROR;
              catch_info.variable = impl()->DeclareCatchVariableName(
                  catch_info.scope, identifier);
5818
            } else {
5819 5820
              catch_info.variable = catch_info.scope->DeclareCatchVariableName(
                  ast_value_factory()->dot_catch_string());
5821 5822 5823

              auto declaration_it = scope()->declarations()->end();

5824 5825
              VariableDeclarationParsingScope destructuring(
                  impl(), VariableMode::kLet, nullptr);
5826
              catch_info.pattern = ParseBindingPattern();
5827 5828 5829 5830 5831 5832 5833 5834

              int initializer_position = end_position();
              auto declaration_end = scope()->declarations()->end();
              for (; declaration_it != declaration_end; ++declaration_it) {
                declaration_it->var()->set_initializer_position(
                    initializer_position);
              }

5835 5836
              RETURN_IF_PARSE_ERROR;
              catch_statements.Add(impl()->RewriteCatchPattern(&catch_info));
5837
            }
5838

5839
            Expect(Token::RPAREN);
5840 5841 5842 5843 5844

            BlockT inner_block = ParseBlock(nullptr);
            catch_statements.Add(inner_block);

            // Check for `catch(e) { let e; }` and similar errors.
5845 5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858
            if (!impl()->HasCheckedSyntax()) {
              Scope* inner_scope = inner_block->scope();
              if (inner_scope != nullptr) {
                const AstRawString* conflict = nullptr;
                if (impl()->IsNull(catch_info.pattern)) {
                  const AstRawString* name = catch_info.variable->raw_name();
                  if (inner_scope->LookupLocal(name)) conflict = name;
                } else {
                  conflict = inner_scope->FindVariableDeclaredIn(
                      scope(), VariableMode::kVar);
                }
                if (conflict != nullptr) {
                  impl()->ReportVarRedeclarationIn(conflict, inner_scope);
                }
5859
              }
5860
            }
5861

5862
            scope()->set_end_position(end_position());
5863
            catch_block = factory()->NewBlock(false, catch_statements);
5864 5865
            catch_block->set_scope(scope()->FinalizeBlockScope());
          }
5866 5867
        }

5868
        catch_info.scope->set_end_position(end_position());
5869
      } else {
5870
        catch_block = ParseBlock(nullptr);
5871
      }
5872
    }
5873 5874
  }

5875
  BlockT finally_block = impl()->NullBlock();
5876 5877
  DCHECK(has_error() || peek() == Token::FINALLY ||
         !impl()->IsNull(catch_block));
5878
  {
5879
    SourceRangeScope range_scope(scanner(), &finally_range);
5880
    if (Check(Token::FINALLY)) {
5881
      finally_block = ParseBlock(nullptr);
5882
    }
5883 5884
  }

5885
  RETURN_IF_PARSE_ERROR;
5886 5887 5888
  return impl()->RewriteTryStatement(try_block, catch_block, catch_range,
                                     finally_block, finally_range, catch_info,
                                     pos);
5889 5890
}

5891 5892
template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForStatement(
5893
    ZonePtrList<const AstRawString>* labels,
5894
    ZonePtrList<const AstRawString>* own_labels) {
5895 5896 5897 5898 5899 5900 5901
  // 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.
5902
  typename FunctionState::LoopScope loop_scope(function_state_);
5903

5904 5905 5906
  int stmt_pos = peek_position();
  ForInfo for_info(this);

5907
  Consume(Token::FOR);
5908
  Expect(Token::LPAREN);
5909

5910 5911
  bool starts_with_let = peek() == Token::LET;
  if (peek() == Token::CONST || (starts_with_let && IsNextLetKeyword())) {
5912 5913
    // The initializer contains lexical declarations,
    // so create an in-between scope.
5914
    BlockState for_state(zone(), &scope_);
5915
    scope()->set_start_position(position());
5916

5917 5918 5919 5920 5921 5922
    // 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_);

5923 5924 5925 5926 5927
    // 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);
5928 5929
      ParseVariableDeclarations(kForStatement, &for_info.parsing_result,
                                &for_info.bound_names);
5930
    }
5931
    DCHECK(IsLexicalVariableMode(for_info.parsing_result.descriptor.mode));
5932
    for_info.position = position();
5933 5934

    if (CheckInOrOf(&for_info.mode)) {
5935
      scope()->set_is_hidden();
5936
      return ParseForEachStatementWithDeclarations(
5937
          stmt_pos, &for_info, labels, own_labels, inner_block_scope);
5938 5939
    }

5940
    Expect(Token::SEMICOLON);
5941

5942 5943 5944 5945 5946 5947 5948
    // Parse the remaining code in the inner block scope since the declaration
    // above was parsed there. We'll finalize the unnecessary outer block scope
    // after parsing the rest of the loop.
    StatementT result = impl()->NullStatement();
    inner_block_scope->set_start_position(scope()->start_position());
    {
      BlockState inner_state(&scope_, inner_block_scope);
5949 5950
      StatementT init =
          impl()->BuildInitializationBlock(&for_info.parsing_result);
5951

5952 5953 5954 5955
      result = ParseStandardForLoopWithLexicalDeclarations(
          stmt_pos, init, &for_info, labels, own_labels);
    }
    Scope* finalized = scope()->FinalizeBlockScope();
5956 5957
    DCHECK_NULL(finalized);
    USE(finalized);
5958
    return result;
5959 5960 5961
  }

  StatementT init = impl()->NullStatement();
5962
  if (peek() == Token::VAR) {
5963 5964
    ParseVariableDeclarations(kForStatement, &for_info.parsing_result,
                              &for_info.bound_names);
5965
    DCHECK_EQ(for_info.parsing_result.descriptor.mode, VariableMode::kVar);
5966 5967 5968 5969
    for_info.position = scanner()->location().beg_pos;

    if (CheckInOrOf(&for_info.mode)) {
      return ParseForEachStatementWithDeclarations(stmt_pos, &for_info, labels,
5970
                                                   own_labels, scope());
5971 5972
    }

5973
    init = impl()->BuildInitializationBlock(&for_info.parsing_result);
5974
  } else if (peek() != Token::SEMICOLON) {
5975
    // The initializer does not contain declarations.
5976 5977
    Scanner::Location next_loc = scanner()->peek_location();
    int lhs_beg_pos = next_loc.beg_pos;
5978 5979
    int lhs_end_pos;
    bool is_for_each;
5980
    ExpressionT expression;
5981

5982
    {
5983
      ExpressionParsingScope parsing_scope(impl());
5984 5985
      AcceptINScope scope(this, false);
      expression = ParseExpressionCoverGrammar();
5986 5987 5988
      // `for (async of` is disallowed but `for (async.x of` is allowed, so
      // check if the token is ASYNC after parsing the expression.
      bool expression_is_async = scanner()->current_token() == Token::ASYNC;
5989 5990 5991 5992
      // Initializer is reference followed by in/of.
      lhs_end_pos = end_position();
      is_for_each = CheckInOrOf(&for_info.mode);
      if (is_for_each) {
5993 5994 5995 5996 5997
        if ((starts_with_let || expression_is_async) &&
            for_info.mode == ForEachStatement::ITERATE) {
          impl()->ReportMessageAt(next_loc, starts_with_let
                                                ? MessageTemplate::kForOfLet
                                                : MessageTemplate::kForOfAsync);
5998 5999
          return impl()->NullStatement();
        }
6000 6001 6002 6003 6004 6005 6006 6007 6008
        if (expression->IsPattern()) {
          parsing_scope.ValidatePattern(expression, lhs_beg_pos, lhs_end_pos);
        } else {
          expression = parsing_scope.ValidateAndRewriteReference(
              expression, lhs_beg_pos, lhs_end_pos);
        }
      } else {
        parsing_scope.ValidateExpression();
      }
6009
    }
6010

6011
    if (is_for_each) {
6012 6013
      return ParseForEachStatementWithoutDeclarations(
          stmt_pos, expression, lhs_beg_pos, lhs_end_pos, &for_info, labels,
6014
          own_labels);
6015 6016 6017 6018
    }
    // Initializer is just an expression.
    init = factory()->NewExpressionStatement(expression, lhs_beg_pos);
  }
6019

6020
  Expect(Token::SEMICOLON);
6021

6022
  // Standard 'for' loop, we have parsed the initializer at this point.
6023
  ExpressionT cond = impl()->NullExpression();
6024 6025
  StatementT next = impl()->NullStatement();
  StatementT body = impl()->NullStatement();
6026 6027 6028
  ForStatementT loop =
      ParseStandardForLoop(stmt_pos, labels, own_labels, &cond, &next, &body);
  RETURN_IF_PARSE_ERROR;
6029 6030
  loop->Initialize(init, cond, next, body);
  return loop;
6031
}
6032

6033 6034 6035
template <typename Impl>
typename ParserBase<Impl>::StatementT
ParserBase<Impl>::ParseForEachStatementWithDeclarations(
6036
    int stmt_pos, ForInfo* for_info, ZonePtrList<const AstRawString>* labels,
6037
    ZonePtrList<const AstRawString>* own_labels, Scope* inner_block_scope) {
6038
  // Just one declaration followed by in/of.
6039
  if (for_info->parsing_result.declarations.size() != 1) {
6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055
    impl()->ReportMessageAt(for_info->parsing_result.bindings_loc,
                            MessageTemplate::kForInOfLoopMultiBindings,
                            ForEachStatement::VisitModeString(for_info->mode));
    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));
    return impl()->NullStatement();
  }
6056

6057
  BlockT init_block = impl()->RewriteForVarInLegacy(*for_info);
6058

6059 6060
  auto loop = factory()->NewForEachStatement(for_info->mode, stmt_pos);
  Target target(this, loop, labels, own_labels, Target::TARGET_FOR_ANONYMOUS);
6061

6062
  ExpressionT enumerable = impl()->NullExpression();
6063
  if (for_info->mode == ForEachStatement::ITERATE) {
6064 6065
    AcceptINScope scope(this, true);
    enumerable = ParseAssignmentExpression();
6066
  } else {
6067
    enumerable = ParseExpression();
6068
  }
6069

6070
  Expect(Token::RPAREN);
6071

6072 6073
  if (IsLexicalVariableMode(for_info->parsing_result.descriptor.mode)) {
    inner_block_scope->set_start_position(position());
6074 6075
  }

6076
  ExpressionT each_variable = impl()->NullExpression();
6077
  BlockT body_block = impl()->NullBlock();
6078
  {
6079
    BlockState block_state(&scope_, inner_block_scope);
6080

6081
    SourceRange body_range;
6082 6083 6084
    StatementT body = impl()->NullStatement();
    {
      SourceRangeScope range_scope(scanner(), &body_range);
6085
      body = ParseStatement(nullptr, nullptr);
6086 6087
    }
    impl()->RecordIterationStatementSourceRange(loop, body_range);
6088

6089 6090
    impl()->DesugarBindingInForEachStatement(for_info, &body_block,
                                             &each_variable);
6091
    body_block->statements()->Add(body, zone());
6092

6093 6094 6095
    if (IsLexicalVariableMode(for_info->parsing_result.descriptor.mode)) {
      scope()->set_end_position(end_position());
      body_block->set_scope(scope()->FinalizeBlockScope());
6096
    }
6097
  }
6098

6099
  loop->Initialize(each_variable, enumerable, body_block);
6100

6101
  init_block = impl()->CreateForEachStatementTDZ(init_block, *for_info);
6102

6103
  // Parsed for-in loop w/ variable declarations.
6104
  if (!impl()->IsNull(init_block)) {
6105
    init_block->statements()->Add(loop, zone());
6106 6107 6108 6109
    if (IsLexicalVariableMode(for_info->parsing_result.descriptor.mode)) {
      scope()->set_end_position(end_position());
      init_block->set_scope(scope()->FinalizeBlockScope());
    }
6110 6111
    return init_block;
  }
6112

6113
  return loop;
6114 6115 6116 6117 6118 6119
}

template <typename Impl>
typename ParserBase<Impl>::StatementT
ParserBase<Impl>::ParseForEachStatementWithoutDeclarations(
    int stmt_pos, ExpressionT expression, int lhs_beg_pos, int lhs_end_pos,
6120
    ForInfo* for_info, ZonePtrList<const AstRawString>* labels,
6121
    ZonePtrList<const AstRawString>* own_labels) {
6122 6123
  auto loop = factory()->NewForEachStatement(for_info->mode, stmt_pos);
  Target target(this, loop, labels, own_labels, Target::TARGET_FOR_ANONYMOUS);
6124

6125
  ExpressionT enumerable = impl()->NullExpression();
6126
  if (for_info->mode == ForEachStatement::ITERATE) {
6127 6128
    AcceptINScope scope(this, true);
    enumerable = ParseAssignmentExpression();
6129
  } else {
6130
    enumerable = ParseExpression();
6131 6132
  }

6133
  Expect(Token::RPAREN);
6134

6135
  StatementT body = impl()->NullStatement();
6136
  SourceRange body_range;
6137
  {
6138
    SourceRangeScope range_scope(scanner(), &body_range);
6139
    body = ParseStatement(nullptr, nullptr);
6140
  }
6141
  impl()->RecordIterationStatementSourceRange(loop, body_range);
6142
  RETURN_IF_PARSE_ERROR;
6143 6144
  loop->Initialize(expression, enumerable, body);
  return loop;
6145 6146 6147
}

template <typename Impl>
6148
typename ParserBase<Impl>::StatementT
6149 6150
ParserBase<Impl>::ParseStandardForLoopWithLexicalDeclarations(
    int stmt_pos, StatementT init, ForInfo* for_info,
6151
    ZonePtrList<const AstRawString>* labels,
6152
    ZonePtrList<const AstRawString>* own_labels) {
6153 6154 6155
  // The condition and the next statement of the for loop must be parsed
  // in a new scope.
  Scope* inner_scope = NewScope(BLOCK_SCOPE);
6156
  ForStatementT loop = impl()->NullStatement();
6157
  ExpressionT cond = impl()->NullExpression();
6158 6159
  StatementT next = impl()->NullStatement();
  StatementT body = impl()->NullStatement();
6160
  {
6161
    BlockState block_state(&scope_, inner_scope);
6162
    scope()->set_start_position(scanner()->location().beg_pos);
6163 6164 6165
    loop =
        ParseStandardForLoop(stmt_pos, labels, own_labels, &cond, &next, &body);
    RETURN_IF_PARSE_ERROR;
6166
    scope()->set_end_position(end_position());
6167 6168
  }

6169
  scope()->set_end_position(end_position());
6170 6171 6172 6173
  if (for_info->bound_names.length() > 0 &&
      function_state_->contains_function_or_eval()) {
    scope()->set_is_hidden();
    return impl()->DesugarLexicalBindingsInForStatement(
6174
        loop, init, cond, next, body, inner_scope, *for_info);
6175 6176 6177 6178
  } else {
    inner_scope = inner_scope->FinalizeBlockScope();
    DCHECK_NULL(inner_scope);
    USE(inner_scope);
6179
  }
6180

6181
  Scope* for_scope = scope()->FinalizeBlockScope();
6182 6183 6184 6185 6186 6187 6188 6189 6190 6191 6192
  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
    //   }
    //
6193
    DCHECK(!impl()->IsNull(init));
6194
    BlockT block = factory()->NewBlock(2, false);
6195
    block->statements()->Add(init, zone());
6196 6197
    block->statements()->Add(loop, zone());
    block->set_scope(for_scope);
6198
    loop->Initialize(impl()->NullStatement(), cond, next, body);
6199 6200 6201
    return block;
  }

6202
  loop->Initialize(init, cond, next, body);
6203 6204 6205 6206 6207
  return loop;
}

template <typename Impl>
typename ParserBase<Impl>::ForStatementT ParserBase<Impl>::ParseStandardForLoop(
6208 6209
    int stmt_pos, ZonePtrList<const AstRawString>* labels,
    ZonePtrList<const AstRawString>* own_labels, ExpressionT* cond,
6210
    StatementT* next, StatementT* body) {
6211
  CheckStackOverflow();
6212 6213
  ForStatementT loop = factory()->NewForStatement(stmt_pos);
  Target target(this, loop, labels, own_labels, Target::TARGET_FOR_ANONYMOUS);
6214 6215

  if (peek() != Token::SEMICOLON) {
6216
    *cond = ParseExpression();
6217
  }
6218
  Expect(Token::SEMICOLON);
6219 6220

  if (peek() != Token::RPAREN) {
6221
    ExpressionT exp = ParseExpression();
6222 6223
    *next = factory()->NewExpressionStatement(exp, exp->position());
  }
6224
  Expect(Token::RPAREN);
6225 6226 6227 6228

  SourceRange body_range;
  {
    SourceRangeScope range_scope(scanner(), &body_range);
6229
    *body = ParseStatement(nullptr, nullptr);
6230
  }
6231
  impl()->RecordIterationStatementSourceRange(loop, body_range);
6232

6233
  return loop;
6234 6235
}

6236 6237
template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForAwaitStatement(
6238
    ZonePtrList<const AstRawString>* labels,
6239
    ZonePtrList<const AstRawString>* own_labels) {
6240
  // for await '(' ForDeclaration of AssignmentExpression ')'
6241
  DCHECK(is_await_allowed());
6242
  typename FunctionState::LoopScope loop_scope(function_state_);
6243 6244 6245 6246 6247 6248 6249

  int stmt_pos = peek_position();

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

  // Create an in-between scope for let-bound iteration variables.
6250
  BlockState for_state(zone(), &scope_);
6251 6252 6253
  Expect(Token::FOR);
  Expect(Token::AWAIT);
  Expect(Token::LPAREN);
6254 6255
  scope()->set_start_position(scanner()->location().beg_pos);
  scope()->set_is_hidden();
6256

6257
  auto loop = factory()->NewForOfStatement(stmt_pos, IteratorType::kAsync);
6258 6259 6260 6261
  // Two suspends: one for next() and one for return()
  function_state_->AddSuspend();
  function_state_->AddSuspend();

6262
  Target target(this, loop, labels, own_labels, Target::TARGET_FOR_ANONYMOUS);
6263

6264
  ExpressionT each_variable = impl()->NullExpression();
6265 6266

  bool has_declarations = false;
6267
  Scope* inner_block_scope = NewScope(BLOCK_SCOPE);
6268

6269
  bool starts_with_let = peek() == Token::LET;
6270
  if (peek() == Token::VAR || peek() == Token::CONST ||
6271
      (starts_with_let && IsNextLetKeyword())) {
6272 6273 6274 6275 6276 6277
    // The initializer contains declarations
    // 'for' 'await' '(' ForDeclaration 'of' AssignmentExpression ')'
    //     Statement
    // 'for' 'await' '(' 'var' ForBinding 'of' AssignmentExpression ')'
    //     Statement
    has_declarations = true;
6278 6279 6280

    {
      BlockState inner_state(&scope_, inner_block_scope);
6281 6282
      ParseVariableDeclarations(kForStatement, &for_info.parsing_result,
                                &for_info.bound_names);
6283
    }
6284 6285 6286
    for_info.position = scanner()->location().beg_pos;

    // Only a single declaration is allowed in for-await-of loops
6287
    if (for_info.parsing_result.declarations.size() != 1) {
6288 6289 6290 6291 6292 6293 6294 6295 6296 6297 6298 6299 6300 6301 6302 6303 6304
      impl()->ReportMessageAt(for_info.parsing_result.bindings_loc,
                              MessageTemplate::kForInOfLoopMultiBindings,
                              "for-await-of");
      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");
      return impl()->NullStatement();
    }
  } else {
    // The initializer does not contain declarations.
    // 'for' 'await' '(' LeftHandSideExpression 'of' AssignmentExpression ')'
    //     Statement
6305 6306 6307 6308 6309
    if (starts_with_let) {
      impl()->ReportMessageAt(scanner()->peek_location(),
                              MessageTemplate::kForOfLet);
      return impl()->NullStatement();
    }
6310
    int lhs_beg_pos = peek_position();
6311
    BlockState inner_state(&scope_, inner_block_scope);
6312
    ExpressionParsingScope parsing_scope(impl());
6313
    ExpressionT lhs = each_variable = ParseLeftHandSideExpression();
6314
    int lhs_end_pos = end_position();
6315

6316
    if (lhs->IsPattern()) {
6317
      parsing_scope.ValidatePattern(lhs, lhs_beg_pos, lhs_end_pos);
6318
    } else {
6319 6320
      each_variable = parsing_scope.ValidateAndRewriteReference(
          lhs, lhs_beg_pos, lhs_end_pos);
6321 6322 6323
    }
  }

6324
  ExpectContextualKeyword(ast_value_factory()->of_string());
6325 6326

  const bool kAllowIn = true;
6327
  ExpressionT iterable = impl()->NullExpression();
6328 6329

  {
6330 6331
    AcceptINScope scope(this, kAllowIn);
    iterable = ParseAssignmentExpression();
6332 6333
  }

6334
  Expect(Token::RPAREN);
6335

6336
  StatementT body = impl()->NullStatement();
6337
  {
6338
    BlockState block_state(&scope_, inner_block_scope);
6339
    scope()->set_start_position(scanner()->location().beg_pos);
6340

6341
    SourceRange body_range;
6342 6343
    {
      SourceRangeScope range_scope(scanner(), &body_range);
6344
      body = ParseStatement(nullptr, nullptr);
6345 6346 6347
      scope()->set_end_position(end_position());
    }
    impl()->RecordIterationStatementSourceRange(loop, body_range);
6348 6349

    if (has_declarations) {
6350
      BlockT body_block = impl()->NullBlock();
6351 6352
      impl()->DesugarBindingInForEachStatement(&for_info, &body_block,
                                               &each_variable);
6353
      body_block->statements()->Add(body, zone());
6354
      body_block->set_scope(scope()->FinalizeBlockScope());
6355
      body = body_block;
6356
    } else {
6357
      Scope* block_scope = scope()->FinalizeBlockScope();
6358 6359 6360 6361
      DCHECK_NULL(block_scope);
      USE(block_scope);
    }
  }
6362 6363

  loop->Initialize(each_variable, iterable, body);
6364 6365 6366 6367 6368

  if (!has_declarations) {
    Scope* for_scope = scope()->FinalizeBlockScope();
    DCHECK_NULL(for_scope);
    USE(for_scope);
6369
    return loop;
6370
  }
6371

6372
  BlockT init_block =
6373
      impl()->CreateForEachStatementTDZ(impl()->NullBlock(), for_info);
6374

6375
  scope()->set_end_position(end_position());
6376
  Scope* for_scope = scope()->FinalizeBlockScope();
6377
  // Parsed for-in loop w/ variable declarations.
6378
  if (!impl()->IsNull(init_block)) {
6379
    init_block->statements()->Add(loop, zone());
6380 6381 6382 6383
    init_block->set_scope(for_scope);
    return init_block;
  }
  DCHECK_NULL(for_scope);
6384
  return loop;
6385 6386
}

6387
template <typename Impl>
6388 6389 6390 6391 6392
void ParserBase<Impl>::CheckClassMethodName(IdentifierT name,
                                            ParsePropertyKind type,
                                            ParseFunctionFlags flags,
                                            bool is_static,
                                            bool* has_seen_constructor) {
6393
  DCHECK(type == ParsePropertyKind::kMethod || IsAccessor(type));
6394

6395
  AstValueFactory* avf = ast_value_factory();
6396

6397 6398 6399 6400
  if (impl()->IdentifierEquals(name, avf->private_constructor_string())) {
    ReportMessage(MessageTemplate::kConstructorIsPrivate);
    return;
  } else if (is_static) {
6401 6402
    if (impl()->IdentifierEquals(name, avf->prototype_string())) {
      ReportMessage(MessageTemplate::kStaticPrototype);
6403 6404
      return;
    }
6405
  } else if (impl()->IdentifierEquals(name, avf->constructor_string())) {
6406
    if (flags != ParseFunctionFlag::kIsNormal || IsAccessor(type)) {
6407 6408 6409 6410 6411
      MessageTemplate msg = (flags & ParseFunctionFlag::kIsGenerator) != 0
                                ? MessageTemplate::kConstructorIsGenerator
                                : (flags & ParseFunctionFlag::kIsAsync) != 0
                                      ? MessageTemplate::kConstructorIsAsync
                                      : MessageTemplate::kConstructorIsAccessor;
6412
      ReportMessage(msg);
6413 6414
      return;
    }
6415 6416
    if (*has_seen_constructor) {
      ReportMessage(MessageTemplate::kDuplicateConstructor);
6417 6418
      return;
    }
6419
    *has_seen_constructor = true;
6420 6421 6422
    return;
  }
}
6423

6424
template <typename Impl>
6425 6426 6427 6428
void ParserBase<Impl>::CheckClassFieldName(IdentifierT name, bool is_static) {
  AstValueFactory* avf = ast_value_factory();
  if (is_static && impl()->IdentifierEquals(name, avf->prototype_string())) {
    ReportMessage(MessageTemplate::kStaticPrototype);
6429 6430 6431
    return;
  }

6432 6433 6434
  if (impl()->IdentifierEquals(name, avf->constructor_string()) ||
      impl()->IdentifierEquals(name, avf->private_constructor_string())) {
    ReportMessage(MessageTemplate::kConstructorClassField);
6435 6436 6437 6438
    return;
  }
}

6439
#undef RETURN_IF_PARSE_ERROR
6440

6441 6442 6443
}  // namespace internal
}  // namespace v8

6444
#endif  // V8_PARSING_PARSER_BASE_H_