parser-base.h 212 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 10
#include <vector>

11
#include "src/ast/ast-source-ranges.h"
12
#include "src/ast/ast.h"
13 14
#include "src/ast/scopes.h"
#include "src/bailout-reason.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"
marja's avatar
marja committed
18
#include "src/counters.h"
19
#include "src/function-kind.h"
yangguo's avatar
yangguo committed
20
#include "src/globals.h"
21
#include "src/log.h"
22
#include "src/message-template.h"
23
#include "src/parsing/expression-scope.h"
24 25 26
#include "src/parsing/func-name-inferrer.h"
#include "src/parsing/scanner.h"
#include "src/parsing/token.h"
27
#include "src/pointer-with-payload.h"
28
#include "src/zone/zone-chunk-list.h"
29 30 31 32 33 34 35 36 37 38

namespace v8 {
namespace internal {

enum FunctionNameValidity {
  kFunctionNameIsStrictReserved,
  kSkipFunctionNameCheck,
  kFunctionNameValidityUnknown
};

39 40 41 42
enum AllowLabelledFunctionStatement {
  kAllowLabelledFunctionStatement,
  kDisallowLabelledFunctionStatement,
};
43

44 45
enum ParsingArrowHeadFlag { kCertainlyNotArrowHead, kMaybeArrowHead };

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

52
using ParseFunctionFlags = base::Flags<ParseFunctionFlag>;
53

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

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

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

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

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

 private:
95
  const Scanner* scanner_;
96 97 98 99
  SourceRange* range_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(SourceRangeScope);
};
100

101
// ----------------------------------------------------------------------------
102 103
// 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
104
// error).
105
//
106 107 108 109 110
// Usage:
//     foo = ParseFoo(); // may fail
//     RETURN_IF_PARSE_ERROR
//
//     SAFE_USE(foo);
111

112 113
#define RETURN_IF_PARSE_ERROR \
  if (has_error()) return impl()->NullStatement();
114

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

178
template <typename Impl>
179
struct ParserTypes;
180

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

194
template <typename Impl>
195
class ParserBase {
196
 public:
197
  // Shorten type names defined by ParserTypes<Impl>.
198 199 200 201 202 203 204 205 206 207 208
  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>;
209 210

  // Return types for traversing functions.
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
  using BlockT = typename Types::Block;
  using BreakableStatementT = typename Types::BreakableStatement;
  using ClassLiteralPropertyT = typename Types::ClassLiteralProperty;
  using ClassPropertyListT = typename Types::ClassPropertyList;
  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;
227
  // For constructing objects returned by the traversing functions.
228
  using FactoryT = typename Types::Factory;
229
  // Other implementation-specific tasks.
230 231 232 233 234 235
  using FuncNameInferrer = typename Types::FuncNameInferrer;
  using FuncNameInferrerState = typename Types::FuncNameInferrer::State;
  using SourceRange = typename Types::SourceRange;
  using SourceRangeScope = typename Types::SourceRangeScope;
  using TargetT = typename Types::Target;
  using TargetScopeT = typename Types::TargetScope;
236

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

241
  ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit,
242
             v8::Extension* extension, AstValueFactory* ast_value_factory,
243
             PendingCompilationErrorHandler* pending_error_handler,
244 245
             RuntimeCallStats* runtime_call_stats, Logger* logger,
             int script_id, bool parsing_module, bool parsing_on_main_thread)
246
      : scope_(nullptr),
247
        original_scope_(nullptr),
248
        function_state_(nullptr),
249
        extension_(extension),
250
        fni_(ast_value_factory),
251
        ast_value_factory_(ast_value_factory),
252
        ast_node_factory_(ast_value_factory, zone),
253
        runtime_call_stats_(runtime_call_stats),
254
        logger_(logger),
255
        parsing_on_main_thread_(parsing_on_main_thread),
256
        parsing_module_(parsing_module),
257
        stack_limit_(stack_limit),
258
        pending_error_handler_(pending_error_handler),
259
        zone_(zone),
260
        expression_scope_(nullptr),
261
        scanner_(scanner),
262
        function_literal_id_(0),
263
        script_id_(script_id),
264
        default_eager_compile_hint_(FunctionLiteral::kShouldLazyCompile),
265
        allow_natives_(false),
266
        allow_harmony_dynamic_import_(false),
267
        allow_harmony_import_meta_(false),
268
        allow_harmony_private_methods_(false),
269
        allow_eval_cache_(true) {
270 271
    pointer_buffer_.reserve(32);
    variable_buffer_.reserve(32);
272
  }
273 274 275 276 277

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

278 279 280 281 282
  ALLOW_ACCESSORS(natives)
  ALLOW_ACCESSORS(harmony_dynamic_import)
  ALLOW_ACCESSORS(harmony_import_meta)
  ALLOW_ACCESSORS(harmony_private_methods)
  ALLOW_ACCESSORS(eval_cache)
283

284 285
#undef ALLOW_ACCESSORS

286
  V8_INLINE bool has_error() const { return scanner()->has_parser_error(); }
287 288 289 290 291 292
  bool allow_harmony_numeric_separator() const {
    return scanner()->allow_harmony_numeric_separator();
  }
  void set_allow_harmony_numeric_separator(bool allow) {
    scanner()->set_allow_harmony_numeric_separator(allow);
  }
293

294 295
  uintptr_t stack_limit() const { return stack_limit_; }

296 297
  void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; }

298 299 300 301 302 303 304 305 306
  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_;
  }

307 308 309 310
  int loop_nesting_depth() const {
    return function_state_->loop_nesting_depth();
  }

311 312 313 314 315 316 317
  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; }

318 319 320 321
  // 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.
322 323
  Zone* zone() const { return zone_; }

324
 protected:
325 326 327
  friend class v8::internal::ExpressionScope<ParserTypes<Impl>>;
  friend class v8::internal::ExpressionParsingScope<ParserTypes<Impl>>;
  friend class v8::internal::ArrowHeadParsingScope<ParserTypes<Impl>>;
328

329 330 331 332 333
  enum VariableDeclarationContext {
    kStatementListItem,
    kStatement,
    kForStatement
  };
334

335
  class ClassLiteralChecker;
336 337

  // ---------------------------------------------------------------------------
338 339 340 341
  // 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.
342
  class BlockState {
343
   public:
344 345 346
    BlockState(Scope** scope_stack, Scope* scope)
        : scope_stack_(scope_stack), outer_scope_(*scope_stack) {
      *scope_stack_ = scope;
347
    }
348

349 350 351
    BlockState(Zone* zone, Scope** scope_stack)
        : BlockState(scope_stack,
                     new (zone) Scope(zone, *scope_stack, BLOCK_SCOPE)) {}
352

353
    ~BlockState() { *scope_stack_ = outer_scope_; }
354 355

   private:
356 357
    Scope** const scope_stack_;
    Scope* const outer_scope_;
358 359
  };

360
  class FunctionState final : public BlockState {
361
   public:
362 363
    FunctionState(FunctionState** function_state_stack, Scope** scope_stack,
                  DeclarationScope* scope);
364 365
    ~FunctionState();

366
    DeclarationScope* scope() const { return scope_->AsDeclarationScope(); }
367

368 369 370
    void AddProperty() { expected_property_count_++; }
    int expected_property_count() { return expected_property_count_; }

371 372 373 374 375
    void DisableOptimization(BailoutReason reason) {
      dont_optimize_reason_ = reason;
    }
    BailoutReason dont_optimize_reason() { return dont_optimize_reason_; }

376 377
    void AddSuspend() { suspend_count_++; }
    int suspend_count() const { return suspend_count_; }
378
    bool CanSuspend() const { return suspend_count_ > 0; }
379

380
    FunctionKind kind() const { return scope()->function_kind(); }
381

382 383
    bool next_function_is_likely_called() const {
      return next_function_is_likely_called_;
384 385
    }

386 387 388 389
    bool previous_function_was_likely_called() const {
      return previous_function_was_likely_called_;
    }

390
    void set_next_function_is_likely_called() {
391
      next_function_is_likely_called_ = !FLAG_max_lazy;
392 393
    }

394 395 396 397 398 399 400 401
    void RecordFunctionOrEvalCall() { contains_function_or_eval_ = true; }
    bool contains_function_or_eval() const {
      return contains_function_or_eval_;
    }

    class FunctionOrEvalRecordingScope {
     public:
      explicit FunctionOrEvalRecordingScope(FunctionState* state)
402
          : state_and_prev_value_(state, state->contains_function_or_eval_) {
403 404 405
        state->contains_function_or_eval_ = false;
      }
      ~FunctionOrEvalRecordingScope() {
406
        bool found = state_and_prev_value_->contains_function_or_eval_;
407
        if (!found) {
408 409
          state_and_prev_value_->contains_function_or_eval_ =
              state_and_prev_value_.GetPayload();
410 411 412 413
        }
      }

     private:
414
      PointerWithPayload<FunctionState, bool, 1> state_and_prev_value_;
415 416
    };

417 418 419 420 421 422 423 424 425 426 427 428 429 430 431
    class LoopScope {
     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_; }

432 433 434 435
   private:
    // Properties count estimation.
    int expected_property_count_;

436 437 438
    // How many suspends are needed for this function.
    int suspend_count_;

439 440 441
    // How deeply nested we currently are in this function.
    int loop_nesting_depth_ = 0;

442 443
    FunctionState** function_state_stack_;
    FunctionState* outer_function_state_;
444
    DeclarationScope* scope_;
445

446 447 448
    // A reason, if any, why this function should not be optimized.
    BailoutReason dont_optimize_reason_;

449
    // Record whether the next (=== immediately following) function literal is
450 451 452 453
    // 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.
454
    bool next_function_is_likely_called_;
455
    bool previous_function_was_likely_called_;
456

457 458 459
    // Track if a function or eval occurs within this FunctionState
    bool contains_function_or_eval_;

460
    friend Impl;
461 462
  };

463 464
  struct DeclarationDescriptor {
    VariableMode mode;
465
    VariableKind kind;
466 467 468 469 470 471
    int declaration_pos;
    int initialization_pos;
  };

  struct DeclarationParsingResult {
    struct Declaration {
472
      Declaration(ExpressionT pattern, ExpressionT initializer)
473 474 475
          : pattern(pattern), initializer(initializer) {
        DCHECK_IMPLIES(Impl::IsNull(pattern), Impl::IsNull(initializer));
      }
476 477 478

      ExpressionT pattern;
      ExpressionT initializer;
479
      int value_beg_pos = kNoSourcePosition;
480 481 482
    };

    DeclarationParsingResult()
483
        : first_initializer_loc(Scanner::Location::invalid()),
484 485 486
          bindings_loc(Scanner::Location::invalid()) {}

    DeclarationDescriptor descriptor;
487
    std::vector<Declaration> declarations;
488 489 490 491
    Scanner::Location first_initializer_loc;
    Scanner::Location bindings_loc;
  };

492 493 494
  struct CatchInfo {
   public:
    explicit CatchInfo(ParserBase* parser)
495 496 497
        : pattern(parser->impl()->NullExpression()),
          variable(nullptr),
          scope(nullptr) {}
498
    ExpressionT pattern;
499
    Variable* variable;
500 501 502
    Scope* scope;
  };

503 504 505 506 507
  struct ForInfo {
   public:
    explicit ForInfo(ParserBase* parser)
        : bound_names(1, parser->zone()),
          mode(ForEachStatement::ENUMERATE),
508
          position(kNoSourcePosition),
509
          parsing_result() {}
510
    ZonePtrList<const AstRawString> bound_names;
511
    ForEachStatement::VisitMode mode;
512
    int position;
513 514 515
    DeclarationParsingResult parsing_result;
  };

516 517 518
  struct ClassInfo {
   public:
    explicit ClassInfo(ParserBase* parser)
519
        : variable(nullptr),
520
          extends(parser->impl()->NullExpression()),
521
          properties(parser->impl()->NewClassPropertyList(4)),
522
          static_fields(parser->impl()->NewClassPropertyList(4)),
523
          instance_fields(parser->impl()->NewClassPropertyList(4)),
524
          constructor(parser->impl()->NullExpression()),
525
          has_seen_constructor(false),
526
          has_name_static_property(false),
527
          has_static_computed_names(false),
528
          has_static_class_fields(false),
529
          has_instance_members(false),
530
          requires_brand(false),
531
          is_anonymous(false),
532
          static_fields_scope(nullptr),
533
          instance_members_scope(nullptr),
534
          computed_field_count(0) {}
535
    Variable* variable;
536
    ExpressionT extends;
537 538 539
    ClassPropertyListT properties;
    ClassPropertyListT static_fields;
    ClassPropertyListT instance_fields;
540
    FunctionLiteralT constructor;
541

542 543 544 545
    bool has_seen_constructor;
    bool has_name_static_property;
    bool has_static_computed_names;
    bool has_static_class_fields;
546
    bool has_instance_members;
547
    bool requires_brand;
548
    bool is_anonymous;
549
    DeclarationScope* static_fields_scope;
550
    DeclarationScope* instance_members_scope;
551
    int computed_field_count;
552 553
  };

554 555 556
  enum class PropertyPosition { kObjectLiteral, kClassLiteral };
  struct ParsePropertyInfo {
   public:
557 558 559 560
    explicit ParsePropertyInfo(ParserBase* parser,
                               AccumulationScope* accumulation_scope = nullptr)
        : accumulation_scope(accumulation_scope),
          name(parser->impl()->NullIdentifier()),
561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599
          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;
    }

600
    AccumulationScope* accumulation_scope;
601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626
    IdentifierT name;
    PropertyPosition position;
    ParseFunctionFlags function_flags;
    ParsePropertyKind kind;
    bool is_computed_name;
    bool is_private;
    bool is_static;
    bool is_rest;
  };

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

627 628 629
  const AstRawString* ClassFieldVariableName(AstValueFactory* ast_value_factory,
                                             int index) {
    std::string name = ".class-field-" + std::to_string(index);
630
    return ast_value_factory->GetOneByteString(name.c_str());
631 632
  }

633
  DeclarationScope* NewScriptScope() const {
634
    return new (zone()) DeclarationScope(zone(), ast_value_factory());
635 636
  }

637
  DeclarationScope* NewVarblockScope() const {
638 639 640
    return new (zone()) DeclarationScope(zone(), scope(), BLOCK_SCOPE);
  }

641
  ModuleScope* NewModuleScope(DeclarationScope* parent) const {
642
    return new (zone()) ModuleScope(parent, ast_value_factory());
643 644
  }

645
  DeclarationScope* NewEvalScope(Scope* parent) const {
646
    return new (zone()) DeclarationScope(zone(), parent, EVAL_SCOPE);
647 648
  }

649 650 651 652
  ClassScope* NewClassScope(Scope* parent) const {
    return new (zone()) ClassScope(zone(), parent);
  }

653
  Scope* NewScope(ScopeType scope_type) const {
654 655 656 657 658 659
    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.
660
  Scope* NewScopeWithParent(Scope* parent, ScopeType scope_type) const {
661 662 663 664
    // Must always use the specific constructors for the blacklisted scope
    // types.
    DCHECK_NE(FUNCTION_SCOPE, scope_type);
    DCHECK_NE(SCRIPT_SCOPE, scope_type);
665
    DCHECK_NE(MODULE_SCOPE, scope_type);
666
    DCHECK_NOT_NULL(parent);
667
    return new (zone()) Scope(zone(), parent, scope_type);
668 669
  }

670 671 672
  // 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.
673 674
  DeclarationScope* NewFunctionScope(FunctionKind kind,
                                     Zone* parse_zone = nullptr) const {
675
    DCHECK(ast_value_factory());
676 677
    if (parse_zone == nullptr) parse_zone = zone();
    DeclarationScope* result = new (zone())
678
        DeclarationScope(parse_zone, scope(), FUNCTION_SCOPE, kind);
679 680 681 682

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

683
    // TODO(verwaest): Move into the DeclarationScope constructor.
684 685 686
    if (!IsArrowFunction(kind)) {
      result->DeclareDefaultFunctionVariables(ast_value_factory());
    }
687 688 689
    return result;
  }

690 691 692 693 694 695 696
  V8_INLINE DeclarationScope* GetDeclarationScope() const {
    return scope()->GetDeclarationScope();
  }
  V8_INLINE DeclarationScope* GetClosureScope() const {
    return scope()->GetClosureScope();
  }

697 698 699 700 701
  VariableProxy* NewRawVariable(const AstRawString* name, int pos) {
    return factory()->ast_node_factory()->NewVariableProxy(
        name, NORMAL_VARIABLE, pos);
  }

702 703 704 705 706 707 708 709 710 711 712
  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);
  }

713 714
  Scanner* scanner() const { return scanner_; }
  AstValueFactory* ast_value_factory() const { return ast_value_factory_; }
715 716
  int position() const { return scanner_->location().beg_pos; }
  int peek_position() const { return scanner_->peek_location().beg_pos; }
717 718
  int end_position() const { return scanner_->location().end_pos; }
  int peek_end_position() const { return scanner_->peek_location().end_pos; }
719 720 721
  bool stack_overflow() const {
    return pending_error_handler()->stack_overflow();
  }
722 723 724 725
  void set_stack_overflow() {
    scanner_->set_parser_error();
    pending_error_handler()->set_stack_overflow();
  }
726 727 728 729
  void CheckStackOverflow() {
    // Any further calls to Next or peek will return the illegal token.
    if (GetCurrentStackPosition() < stack_limit_) set_stack_overflow();
  }
730 731
  int script_id() { return script_id_; }
  void set_script_id(int id) { script_id_ = id; }
732

733
  V8_INLINE Token::Value peek() { return scanner()->peek(); }
734

735 736 737
  // Returns the position past the following semicolon (if it exists), and the
  // position past the end of the current token otherwise.
  int PositionAfterSemicolon() {
738
    return (peek() == Token::SEMICOLON) ? peek_end_position() : end_position();
739 740
  }

741
  V8_INLINE Token::Value PeekAhead() { return scanner()->PeekAhead(); }
742

743
  V8_INLINE Token::Value Next() { return scanner()->Next(); }
744

745
  V8_INLINE void Consume(Token::Value token) {
746
    Token::Value next = scanner()->Next();
747 748
    USE(next);
    USE(token);
749
    DCHECK_IMPLIES(!has_error(), next == token);
750 751
  }

752 753
  V8_INLINE bool Check(Token::Value token) {
    Token::Value next = scanner()->peek();
754 755 756 757 758 759 760
    if (next == token) {
      Consume(next);
      return true;
    }
    return false;
  }

761
  void Expect(Token::Value token) {
762
    Token::Value next = Next();
763
    if (V8_UNLIKELY(next != token)) {
764 765 766 767
      ReportUnexpectedToken(next);
    }
  }

768
  void ExpectSemicolon() {
769 770 771
    // Check for automatic semicolon insertion according to
    // the rules given in ECMA-262, section 7.9, page 21.
    Token::Value tok = peek();
772
    if (V8_LIKELY(tok == Token::SEMICOLON)) {
773 774 775
      Next();
      return;
    }
776 777
    if (V8_LIKELY(scanner()->HasLineTerminatorBeforeNext() ||
                  Token::IsAutoSemicolon(tok))) {
778 779
      return;
    }
780

781 782
    if (scanner()->current_token() == Token::AWAIT && !is_async_function()) {
      ReportMessageAt(scanner()->location(),
783 784 785 786
                      MessageTemplate::kAwaitNotInAsyncFunction, kSyntaxError);
      return;
    }

787
    ReportUnexpectedToken(Next());
788 789
  }

790
  bool peek_any_identifier() { return Token::IsAnyIdentifier(peek()); }
791

792 793
  bool PeekContextualKeyword(const AstRawString* name) {
    return peek() == Token::IDENTIFIER &&
794
           !scanner()->next_literal_contains_escapes() &&
795 796 797 798 799
           scanner()->NextSymbol(ast_value_factory()) == name;
  }

  bool CheckContextualKeyword(const AstRawString* name) {
    if (PeekContextualKeyword(name)) {
800 801 802 803 804 805
      Consume(Token::IDENTIFIER);
      return true;
    }
    return false;
  }

806 807
  void ExpectContextualKeyword(const AstRawString* name,
                               const char* fullname = nullptr, int pos = -1) {
808
    Expect(Token::IDENTIFIER);
809
    if (V8_UNLIKELY(scanner()->CurrentSymbol(ast_value_factory()) != name)) {
810 811
      ReportUnexpectedToken(scanner()->current_token());
    }
812 813 814 815 816 817 818 819 820
    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);
    }
821 822
  }

823
  bool CheckInOrOf(ForEachStatement::VisitMode* visit_mode) {
824
    if (Check(Token::IN)) {
825
      *visit_mode = ForEachStatement::ENUMERATE;
826
      return true;
827
    } else if (CheckContextualKeyword(ast_value_factory()->of_string())) {
828 829 830 831 832 833
      *visit_mode = ForEachStatement::ITERATE;
      return true;
    }
    return false;
  }

834
  bool PeekInOrOf() {
835 836
    return peek() == Token::IN ||
           PeekContextualKeyword(ast_value_factory()->of_string());
837 838
  }

839
  // Checks whether an octal literal was last seen between beg_pos and end_pos.
840
  // Only called for strict mode strings.
841
  void CheckStrictOctalLiteral(int beg_pos, int end_pos) {
842 843 844
    Scanner::Location octal = scanner()->octal_position();
    if (octal.IsValid() && beg_pos <= octal.beg_pos &&
        octal.end_pos <= end_pos) {
845
      MessageTemplate message = scanner()->octal_message();
846
      DCHECK_NE(message, MessageTemplate::kNone);
847
      impl()->ReportMessageAt(octal, message);
848
      scanner()->clear_octal_position();
849 850 851
      if (message == MessageTemplate::kStrictDecimalWithLeadingZero) {
        impl()->CountUsage(v8::Isolate::kDecimalWithLeadingZeroInStrictMode);
      }
852 853 854
    }
  }

855
  // Checks if an octal literal or an invalid hex or unicode escape sequence
856 857 858
  // 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.
859
  inline bool CheckTemplateEscapes(bool should_throw) {
860
    DCHECK(Token::IsTemplate(scanner()->current_token()));
861
    if (!scanner()->has_invalid_template_escape()) return true;
862

863 864 865 866 867
    // Handle error case(s)
    if (should_throw) {
      impl()->ReportMessageAt(scanner()->invalid_template_escape_location(),
                              scanner()->invalid_template_escape_message());
    }
868
    scanner()->clear_invalid_template_escape_message();
869
    return should_throw;
870 871
  }

872 873 874 875
  ExpressionT ParsePossibleDestructuringSubPattern(AccumulationScope* scope);
  void ClassifyParameter(IdentifierT parameter, int beg_pos, int end_pos);
  void ClassifyArrowParameter(AccumulationScope* accumulation_scope,
                              int position, ExpressionT parameter);
876 877 878 879 880

  // 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,
881
                         const Scanner::Location& function_name_loc) {
882
    if (impl()->IsNull(function_name)) return;
883 884 885 886
    if (function_name_validity == kSkipFunctionNameCheck) return;
    // The function name needs to be checked in strict mode.
    if (is_sloppy(language_mode)) return;

887
    if (impl()->IsEvalOrArguments(function_name)) {
888
      impl()->ReportMessageAt(function_name_loc,
889 890 891 892
                              MessageTemplate::kStrictEvalArguments);
      return;
    }
    if (function_name_validity == kFunctionNameIsStrictReserved) {
893
      impl()->ReportMessageAt(function_name_loc,
894 895 896 897 898
                              MessageTemplate::kUnexpectedStrictReserved);
      return;
    }
  }

899
  typename Types::Factory* factory() { return &ast_node_factory_; }
900

901 902 903
  DeclarationScope* GetReceiverScope() const {
    return scope()->GetReceiverScope();
  }
904
  LanguageMode language_mode() { return scope()->language_mode(); }
905 906 907 908
  void RaiseLanguageMode(LanguageMode mode) {
    LanguageMode old = scope()->language_mode();
    impl()->SetLanguageMode(scope(), old > mode ? old : mode);
  }
909 910 911
  bool is_generator() const {
    return IsGeneratorFunction(function_state_->kind());
  }
912
  bool is_async_function() const {
913 914
    return IsAsyncFunction(function_state_->kind());
  }
915 916 917
  bool is_async_generator() const {
    return IsAsyncGeneratorFunction(function_state_->kind());
  }
918 919
  bool is_resumable() const {
    return IsResumableFunction(function_state_->kind());
920
  }
921

922 923 924 925 926 927 928
  const PendingCompilationErrorHandler* pending_error_handler() const {
    return pending_error_handler_;
  }
  PendingCompilationErrorHandler* pending_error_handler() {
    return pending_error_handler_;
  }

929
  // Report syntax errors.
930
  V8_NOINLINE void ReportMessage(MessageTemplate message) {
931
    Scanner::Location source_location = scanner()->location();
932 933
    impl()->ReportMessageAt(source_location, message,
                            static_cast<const char*>(nullptr), kSyntaxError);
934 935
  }

936
  template <typename T>
937 938
  V8_NOINLINE void ReportMessage(MessageTemplate message, T arg,
                                 ParseErrorType error_type = kSyntaxError) {
939
    Scanner::Location source_location = scanner()->location();
940
    impl()->ReportMessageAt(source_location, message, arg, error_type);
941 942
  }

943 944 945
  V8_NOINLINE void ReportMessageAt(Scanner::Location location,
                                   MessageTemplate message,
                                   ParseErrorType error_type) {
946 947
    impl()->ReportMessageAt(location, message,
                            static_cast<const char*>(nullptr), error_type);
948 949
  }

950
  V8_NOINLINE void ReportUnexpectedToken(Token::Value token);
951

952
  void ValidateFormalParameters(LanguageMode language_mode,
953
                                const FormalParametersT& parameters,
954
                                bool allow_duplicates) {
955 956
    if (!allow_duplicates) parameters.ValidateDuplicate(impl());
    if (is_strict(language_mode)) parameters.ValidateStrictMode(impl());
957 958
  }

959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978
  // 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;
  }

979
  V8_INLINE IdentifierT ParseAndClassifyIdentifier(Token::Value token);
980 981 982 983 984 985 986 987 988 989 990
  // 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();
991

992 993
  // This method should be used to ambiguously parse property names that can
  // become destructuring identifiers.
994
  V8_INLINE IdentifierT ParsePropertyName();
995

996
  ExpressionT ParsePropertyOrPrivatePropertyName();
997

998
  ExpressionT ParseRegExpLiteral();
999

1000 1001
  ExpressionT ParseBindingPattern();
  ExpressionT ParsePrimaryExpression();
1002

1003 1004
  // Use when parsing an expression that is known to not be a pattern or part of
  // a pattern.
1005
  V8_INLINE ExpressionT ParseExpression();
1006
  V8_INLINE ExpressionT ParseAssignmentExpression();
1007

1008 1009 1010 1011 1012
  // 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
1013 1014
  // "CoverParenthesizedExpressionAndArrowParameterList" in the ES 2017
  // specification).
1015
  ExpressionT ParseExpressionCoverGrammar();
1016 1017 1018 1019
  ExpressionT ParseAssignmentExpressionCoverGrammar();

  ExpressionT ParseArrowParametersWithRest(ExpressionListT* list,
                                           AccumulationScope* scope);
1020

1021
  ExpressionT ParseArrayLiteral();
1022

1023 1024 1025
  inline static bool IsAccessor(ParsePropertyKind kind) {
    return IsInRange(kind, ParsePropertyKind::kAccessorGetter,
                     ParsePropertyKind::kAccessorSetter);
1026 1027
  }

1028
  ExpressionT ParseProperty(ParsePropertyInfo* prop_info);
1029
  ExpressionT ParseObjectLiteral();
1030
  ClassLiteralPropertyT ParseClassPropertyDefinition(
1031
      ClassInfo* class_info, ParsePropertyInfo* prop_info, bool has_extends);
1032 1033 1034 1035
  void CheckClassFieldName(IdentifierT name, bool is_static);
  void CheckClassMethodName(IdentifierT name, ParsePropertyKind type,
                            ParseFunctionFlags flags, bool is_static,
                            bool* has_seen_constructor);
1036 1037
  ExpressionT ParseMemberInitializer(ClassInfo* class_info, int beg_pos,
                                     bool is_static);
1038 1039
  ObjectLiteralPropertyT ParseObjectPropertyDefinition(
      ParsePropertyInfo* prop_info, bool* has_seen_proto);
1040 1041 1042
  void ParseArguments(
      ExpressionListT* args, bool* has_spread,
      ParsingArrowHeadFlag maybe_arrow = kCertainlyNotArrowHead);
1043

1044 1045 1046 1047 1048
  ExpressionT ParseYieldExpression();
  V8_INLINE ExpressionT ParseConditionalExpression();
  ExpressionT ParseConditionalContinuation(ExpressionT expression, int pos);
  ExpressionT ParseBinaryContinuation(ExpressionT x, int prec, int prec1);
  V8_INLINE ExpressionT ParseBinaryExpression(int prec);
1049
  ExpressionT ParseUnaryOrPrefixExpression();
1050 1051 1052
  ExpressionT ParseAwaitExpression();
  V8_INLINE ExpressionT ParseUnaryExpression();
  V8_INLINE ExpressionT ParsePostfixExpression();
1053 1054
  V8_NOINLINE ExpressionT ParsePostfixContinuation(ExpressionT expression,
                                                   int lhs_beg_pos);
1055 1056 1057 1058 1059
  V8_INLINE ExpressionT ParseLeftHandSideExpression();
  ExpressionT ParseLeftHandSideContinuation(ExpressionT expression);
  ExpressionT ParseMemberWithPresentNewPrefixesExpression();
  ExpressionT ParseFunctionExpression();
  V8_INLINE ExpressionT ParseMemberExpression();
1060
  V8_INLINE ExpressionT
1061
  ParseMemberExpressionContinuation(ExpressionT expression) {
1062
    if (!Token::IsMember(peek())) return expression;
1063
    return DoParseMemberExpressionContinuation(expression);
1064
  }
1065
  ExpressionT DoParseMemberExpressionContinuation(ExpressionT expression);
1066

1067
  ExpressionT ParseArrowFunctionLiteral(const FormalParametersT& parameters);
1068
  void ParseAsyncFunctionBody(Scope* scope, StatementListT* body);
1069
  ExpressionT ParseAsyncFunctionLiteral();
1070 1071 1072
  ExpressionT ParseClassLiteral(IdentifierT name,
                                Scanner::Location class_name_location,
                                bool name_is_strict_reserved,
1073 1074 1075 1076 1077 1078 1079 1080
                                int class_token_pos);
  ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool tagged);
  ExpressionT ParseSuperExpression(bool is_new);
  ExpressionT ParseImportExpressions();
  ExpressionT ParseNewTargetExpression();

  V8_INLINE void ParseFormalParameter(FormalParametersT* parameters);
  void ParseFormalParameterList(FormalParametersT* parameters);
1081 1082
  void CheckArityRestrictions(int param_count, FunctionKind function_type,
                              bool has_rest, int formals_start_pos,
1083
                              int formals_end_pos);
1084

1085
  void ParseVariableDeclarations(VariableDeclarationContext var_context,
1086 1087
                                 DeclarationParsingResult* parsing_result,
                                 ZonePtrList<const AstRawString>* names);
1088
  StatementT ParseAsyncFunctionDeclaration(
1089 1090
      ZonePtrList<const AstRawString>* names, bool default_export);
  StatementT ParseFunctionDeclaration();
1091
  StatementT ParseHoistableDeclaration(ZonePtrList<const AstRawString>* names,
1092
                                       bool default_export);
1093
  StatementT ParseHoistableDeclaration(int pos, ParseFunctionFlags flags,
1094
                                       ZonePtrList<const AstRawString>* names,
1095
                                       bool default_export);
1096
  StatementT ParseClassDeclaration(ZonePtrList<const AstRawString>* names,
1097 1098
                                   bool default_export);
  StatementT ParseNativeDeclaration();
1099

1100 1101
  // Whether we're parsing a single-expression arrow function or something else.
  enum class FunctionBodyType { kExpression, kBlock };
1102
  // Consumes the ending }.
1103
  void ParseFunctionBody(StatementListT* body, IdentifierT function_name,
1104 1105
                         int pos, const FormalParametersT& parameters,
                         FunctionKind kind,
1106
                         FunctionLiteral::FunctionType function_type,
1107
                         FunctionBodyType body_type);
1108

1109 1110 1111 1112 1113 1114 1115 1116 1117
  // 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.
1118
  void CheckConflictingVarDeclarations(DeclarationScope* scope) {
1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133
    if (has_error()) return;
    Declaration* decl = scope->CheckConflictingVarDeclarations();
    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);
    }
  }

1134 1135 1136 1137
  // 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.
1138
  V8_INLINE void ParseStatementList(StatementListT* body,
1139
                                    Token::Value end_token);
1140
  StatementT ParseStatementListItem();
1141 1142

  StatementT ParseStatement(ZonePtrList<const AstRawString>* labels,
1143
                            ZonePtrList<const AstRawString>* own_labels) {
1144
    return ParseStatement(labels, own_labels,
1145
                          kDisallowLabelledFunctionStatement);
1146
  }
1147
  StatementT ParseStatement(ZonePtrList<const AstRawString>* labels,
1148
                            ZonePtrList<const AstRawString>* own_labels,
1149 1150
                            AllowLabelledFunctionStatement allow_function);
  BlockT ParseBlock(ZonePtrList<const AstRawString>* labels);
1151

1152 1153 1154
  // Parse a SubStatement in strict mode, or with an extra block scope in
  // sloppy mode to handle
  // ES#sec-functiondeclarations-in-ifstatement-statement-clauses
1155
  StatementT ParseScopedStatement(ZonePtrList<const AstRawString>* labels);
1156 1157

  StatementT ParseVariableStatement(VariableDeclarationContext var_context,
1158
                                    ZonePtrList<const AstRawString>* names);
1159 1160

  // Magical syntax support.
1161
  ExpressionT ParseV8Intrinsic();
1162

1163
  StatementT ParseDebuggerStatement();
1164

1165
  StatementT ParseExpressionOrLabelledStatement(
1166
      ZonePtrList<const AstRawString>* labels,
1167
      ZonePtrList<const AstRawString>* own_labels,
1168 1169 1170 1171 1172 1173
      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);
1174
  StatementT ParseDoWhileStatement(ZonePtrList<const AstRawString>* labels,
1175
                                   ZonePtrList<const AstRawString>* own_labels);
1176
  StatementT ParseWhileStatement(ZonePtrList<const AstRawString>* labels,
1177 1178 1179 1180
                                 ZonePtrList<const AstRawString>* own_labels);
  StatementT ParseThrowStatement();
  StatementT ParseSwitchStatement(ZonePtrList<const AstRawString>* labels);
  V8_INLINE StatementT ParseTryStatement();
1181
  StatementT ParseForStatement(ZonePtrList<const AstRawString>* labels,
1182
                               ZonePtrList<const AstRawString>* own_labels);
1183
  StatementT ParseForEachStatementWithDeclarations(
1184
      int stmt_pos, ForInfo* for_info, ZonePtrList<const AstRawString>* labels,
1185
      ZonePtrList<const AstRawString>* own_labels, Scope* inner_block_scope);
1186 1187
  StatementT ParseForEachStatementWithoutDeclarations(
      int stmt_pos, ExpressionT expression, int lhs_beg_pos, int lhs_end_pos,
1188
      ForInfo* for_info, ZonePtrList<const AstRawString>* labels,
1189
      ZonePtrList<const AstRawString>* own_labels);
1190

1191 1192
  // Parse a C-style for loop: 'for (<init>; <cond>; <next>) { ... }'
  // "for (<init>;" is assumed to have been parser already.
1193 1194 1195
  ForStatementT ParseStandardForLoop(
      int stmt_pos, ZonePtrList<const AstRawString>* labels,
      ZonePtrList<const AstRawString>* own_labels, ExpressionT* cond,
1196
      StatementT* next, StatementT* body);
1197
  // Same as the above, but handles those cases where <init> is a
1198 1199 1200
  // lexical variable declaration.
  StatementT ParseStandardForLoopWithLexicalDeclarations(
      int stmt_pos, StatementT init, ForInfo* for_info,
1201
      ZonePtrList<const AstRawString>* labels,
1202 1203 1204 1205
      ZonePtrList<const AstRawString>* own_labels);
  StatementT ParseForAwaitStatement(
      ZonePtrList<const AstRawString>* labels,
      ZonePtrList<const AstRawString>* own_labels);
1206

1207 1208 1209 1210
  V8_INLINE bool IsLet(const AstRawString* identifier) const {
    return identifier == ast_value_factory()->let_string();
  }

1211 1212 1213 1214 1215
  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.
1216 1217 1218
  ExpressionT RewriteInvalidReferenceExpression(
      ExpressionT expression, int beg_pos, int end_pos, MessageTemplate message,
      ParseErrorType type = kReferenceError);
1219 1220 1221 1222

  bool IsValidReferenceExpression(ExpressionT expression);

  bool IsAssignableIdentifier(ExpressionT expression) {
1223
    if (!impl()->IsIdentifier(expression)) return false;
1224
    if (is_strict(language_mode()) &&
1225
        impl()->IsEvalOrArguments(impl()->AsIdentifier(expression))) {
1226 1227 1228 1229 1230
      return false;
    }
    return true;
  }

1231
  FunctionKind FunctionKindForImpl(bool is_method, ParseFunctionFlags flags) {
1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248
    static const FunctionKind kFunctionKinds[][2][2] = {
        {
            // is_method=false
            {// is_generator=false
             FunctionKind::kNormalFunction, FunctionKind::kAsyncFunction},
            {// is_generator=true
             FunctionKind::kGeneratorFunction,
             FunctionKind::kAsyncGeneratorFunction},
        },
        {
            // is_method=true
            {// is_generator=false
             FunctionKind::kConciseMethod, FunctionKind::kAsyncConciseMethod},
            {// is_generator=true
             FunctionKind::kConciseGeneratorMethod,
             FunctionKind::kAsyncConciseGeneratorMethod},
        }};
1249 1250 1251
    return kFunctionKinds[is_method]
                         [(flags & ParseFunctionFlag::kIsGenerator) != 0]
                         [(flags & ParseFunctionFlag::kIsAsync) != 0];
1252 1253
  }

1254
  inline FunctionKind FunctionKindFor(ParseFunctionFlags flags) {
1255
    const bool kIsMethod = false;
1256
    return FunctionKindForImpl(kIsMethod, flags);
1257 1258
  }

1259
  inline FunctionKind MethodKindFor(ParseFunctionFlags flags) {
1260
    const bool kIsMethod = true;
1261
    return FunctionKindForImpl(kIsMethod, flags);
1262 1263
  }

1264 1265 1266
  // 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.
1267 1268
  Call::PossiblyEval CheckPossibleEvalCall(ExpressionT expression,
                                           Scope* scope) {
1269 1270
    if (impl()->IsIdentifier(expression) &&
        impl()->IsEval(impl()->AsIdentifier(expression))) {
1271
      scope->RecordInnerScopeEvalCall();
1272
      function_state_->RecordFunctionOrEvalCall();
1273 1274 1275
      if (is_sloppy(scope->language_mode())) {
        // For sloppy scopes we also have to record the call at function level,
        // in case it includes declarations that will be hoisted.
1276
        scope->GetDeclarationScope()->RecordEvalCall();
1277
      }
1278 1279 1280 1281 1282 1283 1284

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

1285
      return Call::IS_POSSIBLY_EVAL;
1286
    }
1287
    return Call::NOT_EVAL;
1288 1289
  }

1290 1291
  // Convenience method which determines the type of return statement to emit
  // depending on the current function type.
1292 1293
  inline StatementT BuildReturnStatement(ExpressionT expr, int pos,
                                         int end_pos = kNoSourcePosition) {
1294
    if (impl()->IsNull(expr)) {
1295
      expr = factory()->NewUndefinedLiteral(kNoSourcePosition);
1296 1297 1298 1299
    } 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);
1300
      function_state_->AddSuspend();
1301 1302 1303 1304 1305
    }
    if (is_async_function()) {
      return factory()->NewAsyncReturnStatement(expr, pos, end_pos);
    }
    return factory()->NewReturnStatement(expr, pos, end_pos);
1306 1307
  }

1308
  ModuleDescriptor* module() const {
1309
    return scope()->AsModuleScope()->module();
1310
  }
1311
  Scope* scope() const { return scope_; }
1312

1313 1314 1315 1316 1317
  // 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_;
1318 1319
  }

1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333
  class AcceptINScope final {
   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_;
  };

1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362
  class ParameterParsingScope {
   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_;
  };

  class FunctionBodyParsingScope {
   public:
    explicit FunctionBodyParsingScope(Impl* parser)
        : parser_(parser), expression_scope_(parser_->expression_scope_) {
      parser_->expression_scope_ = nullptr;
    }

    ~FunctionBodyParsingScope() {
      parser_->expression_scope_ = expression_scope_;
    }

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

1364
  std::vector<void*>* pointer_buffer() { return &pointer_buffer_; }
1365
  std::vector<void*>* variable_buffer() { return &variable_buffer_; }
1366

1367 1368
  // Parser base's protected field members.

1369
  Scope* scope_;                   // Scope stack.
1370
  Scope* original_scope_;  // The top scope for the current parsing item.
1371 1372
  FunctionState* function_state_;  // Function state stack.
  v8::Extension* extension_;
1373
  FuncNameInferrer fni_;
1374
  AstValueFactory* ast_value_factory_;  // Not owned.
1375
  typename Types::Factory ast_node_factory_;
1376
  RuntimeCallStats* runtime_call_stats_;
1377
  internal::Logger* logger_;
1378
  bool parsing_on_main_thread_;
1379
  const bool parsing_module_;
1380
  uintptr_t stack_limit_;
1381
  PendingCompilationErrorHandler* pending_error_handler_;
1382

1383 1384
  // Parser base's private field members.

1385 1386
 private:
  Zone* zone_;
1387
  ExpressionScope* expression_scope_;
1388

1389
  std::vector<void*> pointer_buffer_;
1390
  std::vector<void*> variable_buffer_;
1391

1392 1393
  Scanner* scanner_;

1394
  int function_literal_id_;
1395
  int script_id_;
1396

1397
  FunctionLiteral::EagerCompileHint default_eager_compile_hint_;
1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408

  // 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;
1409
    DeclarationScope* scope = nullptr;
1410

1411
    bool HasInitialState() const { return scope == nullptr; }
1412

1413
    void Reset() {
1414
      scope = nullptr;
1415 1416 1417 1418
      ClearStrictParameterError();
      DCHECK(HasInitialState());
    }

1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430
    // 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_;
1431

1432 1433
  bool accept_IN_ = true;

1434
  bool allow_natives_;
1435
  bool allow_harmony_dynamic_import_;
1436
  bool allow_harmony_import_meta_;
1437
  bool allow_harmony_private_methods_;
1438
  bool allow_eval_cache_;
1439 1440
};

1441 1442
template <typename Impl>
ParserBase<Impl>::FunctionState::FunctionState(
1443
    FunctionState** function_state_stack, Scope** scope_stack,
1444
    DeclarationScope* scope)
1445
    : BlockState(scope_stack, scope),
1446
      expected_property_count_(0),
1447
      suspend_count_(0),
1448 1449
      function_state_stack_(function_state_stack),
      outer_function_state_(*function_state_stack),
1450
      scope_(scope),
1451
      dont_optimize_reason_(BailoutReason::kNoReason),
1452
      next_function_is_likely_called_(false),
1453 1454
      previous_function_was_likely_called_(false),
      contains_function_or_eval_(false) {
1455
  *function_state_stack = this;
1456
  if (outer_function_state_) {
1457 1458
    outer_function_state_->previous_function_was_likely_called_ =
        outer_function_state_->next_function_is_likely_called_;
1459
    outer_function_state_->next_function_is_likely_called_ = false;
1460
  }
1461 1462
}

1463 1464
template <typename Impl>
ParserBase<Impl>::FunctionState::~FunctionState() {
1465 1466 1467
  *function_state_stack_ = outer_function_state_;
}

1468 1469
template <typename Impl>
void ParserBase<Impl>::ReportUnexpectedToken(Token::Value token) {
1470
  return impl()->ReportUnexpectedTokenAt(scanner_->location(), token);
1471 1472
}

1473 1474
template <typename Impl>
typename ParserBase<Impl>::IdentifierT
1475 1476
ParserBase<Impl>::ParseAndClassifyIdentifier(Token::Value next) {
  DCHECK_EQ(scanner()->current_token(), next);
1477
  if (V8_LIKELY(IsInRange(next, Token::IDENTIFIER, Token::ASYNC))) {
1478
    IdentifierT name = impl()->GetIdentifier();
1479 1480 1481 1482
    if (V8_UNLIKELY(impl()->IsArguments(name) &&
                    scope()->ShouldBanArguments())) {
      ReportMessage(MessageTemplate::kArgumentsDisallowedInInitializer);
      return impl()->EmptyIdentifierString();
1483
    }
1484
    return name;
1485 1486
  }

1487
  if (!Token::IsValidIdentifier(next, language_mode(), is_generator(),
1488 1489 1490 1491 1492 1493
                                parsing_module_ || is_async_function())) {
    ReportUnexpectedToken(next);
    return impl()->EmptyIdentifierString();
  }

  if (next == Token::AWAIT) {
1494
    expression_scope()->RecordAsyncArrowParametersError(
1495
        scanner()->location(), MessageTemplate::kAwaitBindingIdentifier);
1496
    return impl()->GetIdentifier();
1497
  }
1498 1499

  DCHECK(Token::IsStrictReservedWord(next));
1500
  expression_scope()->RecordStrictModeParameterError(
1501
      scanner()->location(), MessageTemplate::kUnexpectedStrictReserved);
1502
  return impl()->GetIdentifier();
1503 1504
}

1505
template <class Impl>
1506 1507
typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifier(
    FunctionKind function_kind) {
1508
  Token::Value next = Next();
1509 1510 1511 1512

  if (!Token::IsValidIdentifier(
          next, language_mode(), IsGeneratorFunction(function_kind),
          parsing_module_ || IsAsyncFunction(function_kind))) {
1513
    ReportUnexpectedToken(next);
1514
    return impl()->EmptyIdentifierString();
1515 1516
  }

1517
  return impl()->GetIdentifier();
1518 1519
}

1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533
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;
}

1534
template <typename Impl>
1535
typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParsePropertyName() {
1536
  Token::Value next = Next();
1537 1538 1539 1540
  if (V8_LIKELY(Token::IsPropertyName(next))) {
    if (peek() == Token::COLON) return impl()->GetSymbol();
    return impl()->GetIdentifier();
  }
1541

1542 1543
  ReportUnexpectedToken(next);
  return impl()->EmptyIdentifierString();
1544 1545
}

1546 1547
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
1548
ParserBase<Impl>::ParsePropertyOrPrivatePropertyName() {
1549 1550 1551
  int pos = position();
  IdentifierT name;
  ExpressionT key;
1552 1553 1554 1555
  Token::Value next = Next();
  if (V8_LIKELY(Token::IsPropertyName(next))) {
    name = impl()->GetSymbol();
    key = factory()->NewStringLiteral(name, pos);
1556
  } else if (next == Token::PRIVATE_NAME) {
1557 1558 1559 1560 1561 1562 1563
    // 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.
1564
    ClassScope* class_scope = scope()->GetClassScope();
1565 1566
    // Parse the identifier so that we can display it in the error message
    name = impl()->GetIdentifier();
1567
    if (class_scope == nullptr) {
1568 1569 1570 1571
      impl()->ReportMessageAt(Scanner::Location(pos, pos + 1),
                              MessageTemplate::kInvalidPrivateFieldResolution,
                              impl()->GetRawNameFromIdentifier(name),
                              kSyntaxError);
1572
      return impl()->FailureExpression();
1573
    }
1574
    key = impl()->ExpressionFromPrivateName(class_scope, name, pos);
1575
  } else {
1576 1577
    ReportUnexpectedToken(next);
    return impl()->FailureExpression();
1578 1579 1580 1581 1582
  }
  impl()->PushLiteralName(name);
  return key;
}

1583
template <typename Impl>
1584
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseRegExpLiteral() {
1585
  int pos = peek_position();
1586
  if (!scanner()->ScanRegExpPattern()) {
1587 1588
    Next();
    ReportMessage(MessageTemplate::kUnterminatedRegExp);
1589
    return impl()->FailureExpression();
1590 1591
  }

1592
  IdentifierT js_pattern = impl()->GetNextSymbol();
1593 1594 1595 1596
  Maybe<RegExp::Flags> flags = scanner()->ScanRegExpFlags();
  if (flags.IsNothing()) {
    Next();
    ReportMessage(MessageTemplate::kMalformedRegExpFlags);
1597
    return impl()->FailureExpression();
1598 1599 1600
  }
  int js_flags = flags.FromJust();
  Next();
1601
  return factory()->NewRegExpLiteral(js_pattern, js_flags, pos);
1602 1603
}

1604
template <typename Impl>
1605
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBindingPattern() {
1606 1607 1608 1609 1610 1611 1612 1613 1614 1615
  // Pattern ::
  //   Identifier
  //   ArrayLiteral
  //   ObjectLiteral

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

  if (Token::IsAnyIdentifier(token)) {
1616
    IdentifierT name = ParseAndClassifyIdentifier(Next());
1617 1618 1619 1620
    if (V8_UNLIKELY(is_strict(language_mode()) &&
                    impl()->IsEvalOrArguments(name))) {
      impl()->ReportMessageAt(scanner()->location(),
                              MessageTemplate::kStrictEvalArguments);
1621
      return impl()->FailureExpression();
1622
    }
1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634
    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();
1635 1636 1637 1638 1639
  }

  return result;
}

1640
template <typename Impl>
1641 1642
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParsePrimaryExpression() {
1643 1644
  CheckStackOverflow();

1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659
  // PrimaryExpression ::
  //   'this'
  //   'null'
  //   'true'
  //   'false'
  //   Identifier
  //   Number
  //   String
  //   ArrayLiteral
  //   ObjectLiteral
  //   RegExpLiteral
  //   ClassLiteral
  //   '(' Expression ')'
  //   TemplateLiteral
  //   do Block
1660
  //   AsyncFunctionLiteral
1661 1662

  int beg_pos = peek_position();
1663
  Token::Value token = peek();
1664

1665
  if (Token::IsAnyIdentifier(token)) {
1666 1667
    Consume(token);

1668
    FunctionKind kind = FunctionKind::kArrowFunction;
1669

1670
    if (V8_UNLIKELY(token == Token::ASYNC &&
1671 1672
                    !scanner()->HasLineTerminatorBeforeNext() &&
                    !scanner()->literal_contains_escapes())) {
1673 1674
      // async function ...
      if (peek() == Token::FUNCTION) return ParseAsyncFunctionLiteral();
1675

1676 1677 1678 1679
      // async Identifier => ...
      if (peek_any_identifier() && PeekAhead() == Token::ARROW) {
        token = Next();
        beg_pos = position();
1680
        kind = FunctionKind::kAsyncArrowFunction;
1681 1682
      }
    }
1683

1684
    if (V8_UNLIKELY(peek() == Token::ARROW)) {
1685
      ArrowHeadParsingScope parsing_scope(impl(), kind);
1686
      IdentifierT name = ParseAndClassifyIdentifier(token);
1687
      ClassifyParameter(name, beg_pos, end_position());
1688 1689
      ExpressionT result =
          impl()->ExpressionFromIdentifier(name, beg_pos, InferName::kNo);
1690
      next_arrow_function_info_.scope = parsing_scope.ValidateAndCreateScope();
1691
      return result;
1692
    }
1693

1694 1695
    IdentifierT name = ParseAndClassifyIdentifier(token);
    return impl()->ExpressionFromIdentifier(name, beg_pos);
1696 1697 1698 1699 1700 1701
  }

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

1702
  switch (token) {
1703 1704 1705
    case Token::NEW:
      return ParseMemberWithPresentNewPrefixesExpression();

1706 1707
    case Token::THIS: {
      Consume(Token::THIS);
1708
      return impl()->ThisExpression();
1709 1710 1711 1712
    }

    case Token::ASSIGN_DIV:
    case Token::DIV:
1713
      return ParseRegExpLiteral();
1714

1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725
    case Token::FUNCTION:
      return ParseFunctionExpression();

    case Token::SUPER: {
      const bool is_new = false;
      return ParseSuperExpression(is_new);
    }
    case Token::IMPORT:
      if (!allow_harmony_dynamic_import()) break;
      return ParseImportExpressions();

1726
    case Token::LBRACK:
1727
      return ParseArrayLiteral();
1728 1729

    case Token::LBRACE:
1730
      return ParseObjectLiteral();
1731 1732 1733 1734

    case Token::LPAREN: {
      Consume(Token::LPAREN);
      if (Check(Token::RPAREN)) {
1735
        // ()=>x.  The continuation that consumes the => is in
1736
        // ParseAssignmentExpressionCoverGrammar.
1737
        if (peek() != Token::ARROW) ReportUnexpectedToken(Token::RPAREN);
1738 1739
        next_arrow_function_info_.scope =
            NewFunctionScope(FunctionKind::kArrowFunction);
1740 1741
        return factory()->NewEmptyParentheses(beg_pos);
      }
1742
      Scope::Snapshot scope_snapshot(scope());
1743
      ArrowHeadParsingScope maybe_arrow(impl(), FunctionKind::kArrowFunction);
1744 1745
      // Heuristically try to detect immediately called functions before
      // seeing the call parentheses.
1746 1747
      if (peek() == Token::FUNCTION ||
          (peek() == Token::ASYNC && PeekAhead() == Token::FUNCTION)) {
1748 1749
        function_state_->set_next_function_is_likely_called();
      }
1750 1751
      AcceptINScope scope(this, true);
      ExpressionT expr = ParseExpressionCoverGrammar();
1752
      expr->mark_parenthesized();
1753
      Expect(Token::RPAREN);
1754 1755

      if (peek() == Token::ARROW) {
1756
        next_arrow_function_info_.scope = maybe_arrow.ValidateAndCreateScope();
1757
        scope_snapshot.Reparent(next_arrow_function_info_.scope);
1758 1759
      } else {
        maybe_arrow.ValidateExpression();
1760 1761
      }

1762 1763 1764 1765 1766
      return expr;
    }

    case Token::CLASS: {
      Consume(Token::CLASS);
1767
      int class_token_pos = position();
1768
      IdentifierT name = impl()->NullIdentifier();
1769 1770 1771
      bool is_strict_reserved_name = false;
      Scanner::Location class_name_location = Scanner::Location::invalid();
      if (peek_any_identifier()) {
1772
        name = ParseAndClassifyIdentifier(Next());
1773
        class_name_location = scanner()->location();
1774 1775
        is_strict_reserved_name =
            Token::IsStrictReservedWord(scanner()->current_token());
1776
      }
1777
      return ParseClassLiteral(name, class_name_location,
1778
                               is_strict_reserved_name, class_token_pos);
1779 1780 1781 1782
    }

    case Token::TEMPLATE_SPAN:
    case Token::TEMPLATE_TAIL:
1783
      return ParseTemplateLiteral(impl()->NullExpression(), beg_pos, false);
1784 1785

    case Token::MOD:
1786
      if (allow_natives() || extension_ != nullptr) {
1787
        return ParseV8Intrinsic();
1788 1789 1790 1791 1792 1793 1794 1795
      }
      break;

    default:
      break;
  }

  ReportUnexpectedToken(Next());
1796
  return impl()->FailureExpression();
1797 1798
}

1799
template <typename Impl>
1800
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression() {
1801
  ExpressionParsingScope expression_scope(impl());
1802 1803
  AcceptINScope scope(this, true);
  ExpressionT result = ParseExpressionCoverGrammar();
1804 1805 1806 1807 1808 1809 1810 1811 1812 1813
  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();
1814 1815 1816
  return result;
}

1817
template <typename Impl>
1818
typename ParserBase<Impl>::ExpressionT
1819
ParserBase<Impl>::ParseExpressionCoverGrammar() {
1820 1821 1822 1823
  // Expression ::
  //   AssignmentExpression
  //   Expression ',' AssignmentExpression

1824
  ExpressionListT list(pointer_buffer());
1825
  ExpressionT expression;
1826
  AccumulationScope accumulation_scope(expression_scope());
1827
  while (true) {
1828
    if (V8_UNLIKELY(peek() == Token::ELLIPSIS)) {
1829
      return ParseArrowParametersWithRest(&list, &accumulation_scope);
1830
    }
1831

1832 1833 1834 1835
    int expr_pos = peek_position();
    expression = ParseAssignmentExpressionCoverGrammar();

    ClassifyArrowParameter(&accumulation_scope, expr_pos, expression);
1836
    list.Add(expression);
1837 1838 1839

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

1840
    if (peek() == Token::RPAREN && PeekAhead() == Token::ARROW) {
1841 1842
      // a trailing comma is allowed at the end of an arrow parameter list
      break;
1843
    }
1844 1845 1846 1847 1848 1849 1850

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

1853 1854 1855 1856
  // 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.
1857
  if (list.length() == 1) return expression;
1858
  return impl()->ExpressionListToExpression(list);
1859 1860
}

1861 1862
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
1863 1864 1865
ParserBase<Impl>::ParseArrowParametersWithRest(
    typename ParserBase<Impl>::ExpressionListT* list,
    AccumulationScope* accumulation_scope) {
1866 1867 1868 1869 1870
  Consume(Token::ELLIPSIS);

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

1873
  expression_scope()->RecordNonSimpleParameter();
1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890

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

  // '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) {
1891
    impl()->ReportUnexpectedTokenAt(ellipsis, Token::ELLIPSIS);
1892 1893 1894 1895 1896 1897 1898
    return impl()->FailureExpression();
  }

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

1899
template <typename Impl>
1900
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseArrayLiteral() {
1901 1902 1903 1904
  // ArrayLiteral ::
  //   '[' Expression? (',' Expression?)* ']'

  int pos = peek_position();
1905
  ExpressionListT values(pointer_buffer());
1906
  int first_spread_index = -1;
1907
  Consume(Token::LBRACK);
1908 1909 1910

  AccumulationScope accumulation_scope(expression_scope());

1911
  while (!Check(Token::RBRACK)) {
1912
    ExpressionT elem;
1913
    if (peek() == Token::COMMA) {
1914
      elem = factory()->NewTheHoleLiteral();
1915 1916
    } else if (Check(Token::ELLIPSIS)) {
      int start_pos = position();
nikolaos's avatar
nikolaos committed
1917
      int expr_pos = peek_position();
1918
      AcceptINScope scope(this, true);
1919 1920
      ExpressionT argument =
          ParsePossibleDestructuringSubPattern(&accumulation_scope);
nikolaos's avatar
nikolaos committed
1921
      elem = factory()->NewSpread(argument, start_pos, expr_pos);
1922 1923

      if (first_spread_index < 0) {
1924
        first_spread_index = values.length();
1925 1926
      }

1927
      if (argument->IsAssignment()) {
1928
        expression_scope()->RecordPatternError(
1929
            Scanner::Location(start_pos, end_position()),
1930 1931
            MessageTemplate::kInvalidDestructuringTarget);
      }
1932 1933

      if (peek() == Token::COMMA) {
1934
        expression_scope()->RecordPatternError(
1935
            Scanner::Location(start_pos, end_position()),
1936 1937 1938
            MessageTemplate::kElementAfterRest);
      }
    } else {
1939
      AcceptINScope scope(this, true);
1940
      elem = ParsePossibleDestructuringSubPattern(&accumulation_scope);
1941
    }
1942
    values.Add(elem);
1943
    if (peek() != Token::RBRACK) {
1944
      Expect(Token::COMMA);
1945
      if (elem->IsFailureExpression()) return elem;
1946 1947 1948
    }
  }

1949
  return factory()->NewArrayLiteral(values, first_spread_index, pos);
1950 1951
}

1952
template <class Impl>
1953
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseProperty(
1954 1955 1956 1957
    ParsePropertyInfo* prop_info) {
  DCHECK_EQ(prop_info->kind, ParsePropertyKind::kNotSet);
  DCHECK_EQ(prop_info->function_flags, ParseFunctionFlag::kIsNormal);
  DCHECK(!prop_info->is_computed_name);
1958

1959 1960
  if (Check(Token::ASYNC)) {
    Token::Value token = peek();
1961
    if ((token != Token::MUL && prop_info->ParsePropertyKindFromToken(token)) ||
1962
        scanner()->HasLineTerminatorBeforeNext()) {
1963
      prop_info->name = impl()->GetIdentifier();
1964 1965
      impl()->PushLiteralName(prop_info->name);
      return factory()->NewStringLiteral(prop_info->name, position());
1966
    }
1967 1968 1969
    if (V8_UNLIKELY(scanner()->literal_contains_escapes())) {
      impl()->ReportUnexpectedToken(Token::ESCAPED_KEYWORD);
    }
1970 1971
    prop_info->function_flags = ParseFunctionFlag::kIsAsync;
    prop_info->kind = ParsePropertyKind::kMethod;
1972 1973
  }

1974
  if (Check(Token::MUL)) {
1975 1976
    prop_info->function_flags |= ParseFunctionFlag::kIsGenerator;
    prop_info->kind = ParsePropertyKind::kMethod;
1977 1978
  }

1979
  if (prop_info->kind == ParsePropertyKind::kNotSet &&
1980 1981 1982
      IsInRange(peek(), Token::GET, Token::SET)) {
    Token::Value token = Next();
    if (prop_info->ParsePropertyKindFromToken(peek())) {
1983
      prop_info->name = impl()->GetIdentifier();
1984 1985
      impl()->PushLiteralName(prop_info->name);
      return factory()->NewStringLiteral(prop_info->name, position());
1986
    }
1987 1988 1989 1990 1991 1992 1993 1994
    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;
    }
1995 1996
  }

1997 1998
  int pos = peek_position();

1999 2000 2001 2002 2003 2004 2005 2006 2007
  // 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.
2008 2009 2010
  bool is_array_index;
  uint32_t index;
  switch (peek()) {
2011
    case Token::PRIVATE_NAME:
2012
      prop_info->is_private = true;
2013 2014
      is_array_index = false;
      Consume(Token::PRIVATE_NAME);
2015 2016
      if (prop_info->kind == ParsePropertyKind::kNotSet) {
        prop_info->ParsePropertyKindFromToken(peek());
2017
      }
2018
      prop_info->name = impl()->GetIdentifier();
2019 2020 2021 2022 2023 2024 2025 2026 2027
      if (V8_UNLIKELY(prop_info->position ==
                      PropertyPosition::kObjectLiteral)) {
        ReportUnexpectedToken(Token::PRIVATE_NAME);
        prop_info->kind = ParsePropertyKind::kNotSet;
        return impl()->FailureExpression();
      }
      if (V8_UNLIKELY(!allow_harmony_private_methods() &&
                      (IsAccessor(prop_info->kind) ||
                       prop_info->kind == ParsePropertyKind::kMethod))) {
2028
        ReportUnexpectedToken(Next());
2029
        prop_info->kind = ParsePropertyKind::kNotSet;
2030 2031 2032 2033
        return impl()->FailureExpression();
      }
      break;

2034 2035
    case Token::STRING:
      Consume(Token::STRING);
2036 2037
      prop_info->name = peek() == Token::COLON ? impl()->GetSymbol()
                                               : impl()->GetIdentifier();
2038
      is_array_index = impl()->IsArrayIndex(prop_info->name, &index);
2039 2040 2041 2042
      break;

    case Token::SMI:
      Consume(Token::SMI);
2043 2044 2045
      index = scanner()->smi_value();
      is_array_index = true;
      // Token::SMI were scanned from their canonical representation.
2046
      prop_info->name = impl()->GetSymbol();
2047 2048
      break;

2049
    case Token::NUMBER: {
2050
      Consume(Token::NUMBER);
2051 2052
      prop_info->name = impl()->GetNumberAsSymbol();
      is_array_index = impl()->IsArrayIndex(prop_info->name, &index);
2053
      break;
2054
    }
2055
    case Token::LBRACK: {
2056 2057
      prop_info->name = impl()->NullIdentifier();
      prop_info->is_computed_name = true;
2058
      Consume(Token::LBRACK);
2059 2060
      AcceptINScope scope(this, true);
      ExpressionT expression = ParseAssignmentExpression();
2061
      Expect(Token::RBRACK);
2062 2063
      if (prop_info->kind == ParsePropertyKind::kNotSet) {
        prop_info->ParsePropertyKindFromToken(peek());
2064 2065
      }
      return expression;
2066 2067
    }

2068
    case Token::ELLIPSIS:
2069 2070
      if (prop_info->kind == ParsePropertyKind::kNotSet) {
        prop_info->name = impl()->NullIdentifier();
2071
        Consume(Token::ELLIPSIS);
2072
        AcceptINScope scope(this, true);
2073 2074 2075
        int start_pos = peek_position();
        ExpressionT expression =
            ParsePossibleDestructuringSubPattern(prop_info->accumulation_scope);
2076
        prop_info->kind = ParsePropertyKind::kSpread;
2077

2078
        if (!IsValidReferenceExpression(expression)) {
2079 2080
          expression_scope()->RecordDeclarationError(
              Scanner::Location(start_pos, end_position()),
2081
              MessageTemplate::kInvalidRestBindingPattern);
2082 2083
          expression_scope()->RecordPatternError(
              Scanner::Location(start_pos, end_position()),
2084
              MessageTemplate::kInvalidRestAssignmentPattern);
2085 2086 2087
        }

        if (peek() != Token::RBRACE) {
2088 2089
          expression_scope()->RecordPatternError(
              scanner()->location(), MessageTemplate::kElementAfterRest);
2090
        }
2091 2092
        return expression;
      }
2093
      V8_FALLTHROUGH;
2094

2095
    default:
2096
      prop_info->name = ParsePropertyName();
2097
      is_array_index = false;
2098 2099 2100
      break;
  }

2101 2102
  if (prop_info->kind == ParsePropertyKind::kNotSet) {
    prop_info->ParsePropertyKindFromToken(peek());
2103
  }
2104
  impl()->PushLiteralName(prop_info->name);
2105
  return is_array_index ? factory()->NewNumberLiteral(index, pos)
2106
                        : factory()->NewStringLiteral(prop_info->name, pos);
2107 2108
}

2109
template <typename Impl>
2110
typename ParserBase<Impl>::ClassLiteralPropertyT
2111 2112 2113
ParserBase<Impl>::ParseClassPropertyDefinition(ClassInfo* class_info,
                                               ParsePropertyInfo* prop_info,
                                               bool has_extends) {
2114
  DCHECK_NOT_NULL(class_info);
2115
  DCHECK_EQ(prop_info->position, PropertyPosition::kClassLiteral);
2116

2117
  Token::Value name_token = peek();
2118 2119
  int property_beg_pos = scanner()->peek_location().beg_pos;
  int name_token_position = property_beg_pos;
2120 2121 2122
  ExpressionT name_expression;
  if (name_token == Token::STATIC) {
    Consume(Token::STATIC);
2123
    name_token_position = scanner()->peek_location().beg_pos;
2124
    if (peek() == Token::LPAREN) {
2125 2126
      prop_info->kind = ParsePropertyKind::kMethod;
      // TODO(bakkot) specialize on 'static'
2127
      prop_info->name = impl()->GetIdentifier();
2128 2129
      name_expression =
          factory()->NewStringLiteral(prop_info->name, position());
2130 2131
    } else if (peek() == Token::ASSIGN || peek() == Token::SEMICOLON ||
               peek() == Token::RBRACE) {
2132
      // TODO(bakkot) specialize on 'static'
2133
      prop_info->name = impl()->GetIdentifier();
2134 2135
      name_expression =
          factory()->NewStringLiteral(prop_info->name, position());
2136
    } else {
2137
      prop_info->is_static = true;
2138
      name_expression = ParseProperty(prop_info);
2139
    }
2140
  } else {
2141
    name_expression = ParseProperty(prop_info);
2142 2143
  }

2144 2145
  if (!class_info->has_name_static_property && prop_info->is_static &&
      impl()->IsName(prop_info->name)) {
2146
    class_info->has_name_static_property = true;
2147 2148
  }

2149
  switch (prop_info->kind) {
2150
    case ParsePropertyKind::kAssign:
2151
    case ParsePropertyKind::kClassField:
2152
    case ParsePropertyKind::kShorthandOrClassField:
2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163
    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);
2164

2165 2166 2167
      if (!prop_info->is_computed_name) {
        CheckClassFieldName(prop_info->name, prop_info->is_static);
      }
2168

2169 2170 2171
      ExpressionT initializer = ParseMemberInitializer(
          class_info, property_beg_pos, prop_info->is_static);
      ExpectSemicolon();
2172

2173 2174 2175 2176 2177
      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);
2178

2179 2180
      return result;
    }
2181
    case ParsePropertyKind::kMethod: {
2182 2183 2184
      // MethodDefinition
      //    PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
      //    '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2185 2186 2187 2188
      //    async PropertyName '(' StrictFormalParameters ')'
      //        '{' FunctionBody '}'
      //    async '*' PropertyName '(' StrictFormalParameters ')'
      //        '{' FunctionBody '}'
2189

2190 2191 2192 2193
      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);
2194 2195
      }

2196
      FunctionKind kind = MethodKindFor(prop_info->function_flags);
2197

2198
      if (!prop_info->is_static && impl()->IsConstructor(prop_info->name)) {
2199
        class_info->has_seen_constructor = true;
2200
        kind = has_extends ? FunctionKind::kDerivedConstructor
2201 2202 2203 2204
                           : FunctionKind::kBaseConstructor;
      }

      ExpressionT value = impl()->ParseFunctionLiteral(
2205
          prop_info->name, scanner()->location(), kSkipFunctionNameCheck, kind,
2206
          name_token_position, FunctionLiteral::kAccessorOrMethod,
2207
          language_mode(), nullptr);
2208

2209
      ClassLiteralPropertyT result = factory()->NewClassLiteralProperty(
2210 2211 2212 2213
          name_expression, value, ClassLiteralProperty::METHOD,
          prop_info->is_static, prop_info->is_computed_name,
          prop_info->is_private);
      impl()->SetFunctionNameFromPropertyName(result, prop_info->name);
2214
      return result;
2215 2216
    }

2217 2218
    case ParsePropertyKind::kAccessorGetter:
    case ParsePropertyKind::kAccessorSetter: {
2219 2220
      DCHECK_EQ(prop_info->function_flags, ParseFunctionFlag::kIsNormal);
      bool is_get = prop_info->kind == ParsePropertyKind::kAccessorGetter;
2221

2222 2223 2224 2225
      if (!prop_info->is_computed_name) {
        CheckClassMethodName(prop_info->name, prop_info->kind,
                             ParseFunctionFlag::kIsNormal, prop_info->is_static,
                             &class_info->has_seen_constructor);
2226 2227 2228
        // 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.
2229 2230
        name_expression = factory()->NewStringLiteral(
            prop_info->name, name_expression->position());
2231 2232 2233 2234 2235
      }

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

2236
      FunctionLiteralT value = impl()->ParseFunctionLiteral(
2237
          prop_info->name, scanner()->location(), kSkipFunctionNameCheck, kind,
2238
          name_token_position, FunctionLiteral::kAccessorOrMethod,
2239
          language_mode(), nullptr);
2240

2241
      ClassLiteralProperty::Kind property_kind =
2242
          is_get ? ClassLiteralProperty::GETTER : ClassLiteralProperty::SETTER;
2243
      ClassLiteralPropertyT result = factory()->NewClassLiteralProperty(
2244 2245
          name_expression, value, property_kind, prop_info->is_static,
          prop_info->is_computed_name, prop_info->is_private);
2246 2247 2248
      const AstRawString* prefix =
          is_get ? ast_value_factory()->get_space_string()
                 : ast_value_factory()->set_space_string();
2249
      impl()->SetFunctionNameFromPropertyName(result, prop_info->name, prefix);
2250
      return result;
2251
    }
2252 2253
    case ParsePropertyKind::kValue:
    case ParsePropertyKind::kShorthand:
2254
    case ParsePropertyKind::kSpread:
2255
      impl()->ReportUnexpectedTokenAt(
2256 2257
          Scanner::Location(name_token_position, name_expression->position()),
          name_token);
2258
      return impl()->NullLiteralProperty();
2259 2260 2261 2262
  }
  UNREACHABLE();
}

2263
template <typename Impl>
2264 2265 2266 2267 2268
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseMemberInitializer(
    ClassInfo* class_info, int beg_pos, bool is_static) {
  DeclarationScope* initializer_scope =
      is_static ? class_info->static_fields_scope
                : class_info->instance_members_scope;
2269 2270

  if (initializer_scope == nullptr) {
2271
    initializer_scope =
2272
        NewFunctionScope(FunctionKind::kClassMembersInitializerFunction);
2273
    // TODO(gsathya): Make scopes be non contiguous.
2274
    initializer_scope->set_start_position(beg_pos);
2275 2276 2277 2278 2279 2280 2281 2282
    initializer_scope->SetLanguageMode(LanguageMode::kStrict);
  }

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

2283 2284
    AcceptINScope scope(this, true);
    initializer = ParseAssignmentExpression();
2285
  } else {
2286
    initializer = factory()->NewUndefinedLiteral(kNoSourcePosition);
2287
  }
2288

2289
  initializer_scope->set_end_position(end_position());
2290 2291 2292 2293
  if (is_static) {
    class_info->static_fields_scope = initializer_scope;
    class_info->has_static_class_fields = true;
  } else {
2294 2295
    class_info->instance_members_scope = initializer_scope;
    class_info->has_instance_members = true;
2296 2297 2298
  }

  return initializer;
2299 2300
}

2301 2302
template <typename Impl>
typename ParserBase<Impl>::ObjectLiteralPropertyT
2303 2304 2305
ParserBase<Impl>::ParseObjectPropertyDefinition(ParsePropertyInfo* prop_info,
                                                bool* has_seen_proto) {
  DCHECK_EQ(prop_info->position, PropertyPosition::kObjectLiteral);
2306
  Token::Value name_token = peek();
2307
  Scanner::Location next_loc = scanner()->peek_location();
2308

2309
  ExpressionT name_expression = ParseProperty(prop_info);
2310 2311 2312

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

2313 2314 2315
  IdentifierT name = prop_info->name;
  ParseFunctionFlags function_flags = prop_info->function_flags;
  ParsePropertyKind kind = prop_info->kind;
2316

2317
  switch (prop_info->kind) {
2318
    case ParsePropertyKind::kSpread:
2319
      DCHECK_EQ(function_flags, ParseFunctionFlag::kIsNormal);
2320
      DCHECK(!prop_info->is_computed_name);
2321
      DCHECK_EQ(Token::ELLIPSIS, name_token);
2322

2323 2324
      prop_info->is_computed_name = true;
      prop_info->is_rest = true;
2325 2326

      return factory()->NewObjectLiteralProperty(
2327
          factory()->NewTheHoleLiteral(), name_expression,
2328 2329
          ObjectLiteralProperty::SPREAD, true);

2330
    case ParsePropertyKind::kValue: {
2331
      DCHECK_EQ(function_flags, ParseFunctionFlag::kIsNormal);
2332

2333
      if (!prop_info->is_computed_name &&
2334
          scanner()->CurrentLiteralEquals("__proto__")) {
2335
        if (*has_seen_proto) {
2336 2337
          expression_scope()->RecordExpressionError(
              scanner()->location(), MessageTemplate::kDuplicateProto);
2338 2339
        }
        *has_seen_proto = true;
2340 2341
      }
      Consume(Token::COLON);
2342
      AcceptINScope scope(this, true);
2343 2344
      ExpressionT value =
          ParsePossibleDestructuringSubPattern(prop_info->accumulation_scope);
2345

2346
      ObjectLiteralPropertyT result = factory()->NewObjectLiteralProperty(
2347
          name_expression, value, prop_info->is_computed_name);
2348
      impl()->SetFunctionNameFromPropertyName(result, name);
2349
      return result;
2350 2351
    }

2352 2353
    case ParsePropertyKind::kAssign:
    case ParsePropertyKind::kShorthandOrClassField:
2354
    case ParsePropertyKind::kShorthand: {
2355 2356 2357 2358 2359 2360
      // PropertyDefinition
      //    IdentifierReference
      //    CoverInitializedName
      //
      // CoverInitializedName
      //    IdentifierReference Initializer?
2361
      DCHECK_EQ(function_flags, ParseFunctionFlag::kIsNormal);
2362

2363
      if (!Token::IsValidIdentifier(name_token, language_mode(), is_generator(),
2364
                                    parsing_module_ || is_async_function())) {
2365
        ReportUnexpectedToken(Next());
2366
        return impl()->NullLiteralProperty();
2367 2368
      }

2369
      DCHECK(!prop_info->is_computed_name);
2370

2371 2372
      if (name_token == Token::AWAIT) {
        DCHECK(!is_async_function());
2373
        expression_scope()->RecordAsyncArrowParametersError(
2374 2375 2376 2377 2378
            next_loc, MessageTemplate::kAwaitBindingIdentifier);
      }
      ExpressionT lhs =
          impl()->ExpressionFromIdentifier(name, next_loc.beg_pos);
      if (!IsAssignableIdentifier(lhs)) {
2379 2380
        expression_scope()->RecordPatternError(
            next_loc, MessageTemplate::kStrictEvalArguments);
2381
      }
2382

2383
      ExpressionT value;
2384 2385
      if (peek() == Token::ASSIGN) {
        Consume(Token::ASSIGN);
2386 2387 2388 2389 2390 2391 2392 2393
        {
          AcceptINScope scope(this, true);
          ExpressionT rhs = ParseAssignmentExpression();
          value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs,
                                           kNoSourcePosition);
          impl()->SetFunctionNameFromIdentifierRef(rhs, lhs);
        }
        expression_scope()->RecordExpressionError(
2394
            Scanner::Location(next_loc.beg_pos, end_position()),
2395 2396 2397 2398 2399
            MessageTemplate::kInvalidCoverInitializedName);
      } else {
        value = lhs;
      }

2400
      ObjectLiteralPropertyT result = factory()->NewObjectLiteralProperty(
2401
          name_expression, value, ObjectLiteralProperty::COMPUTED, false);
2402 2403
      impl()->SetFunctionNameFromPropertyName(result, name);
      return result;
2404 2405
    }

2406
    case ParsePropertyKind::kMethod: {
2407 2408 2409
      // MethodDefinition
      //    PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
      //    '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2410

2411
      expression_scope()->RecordPatternError(
2412
          Scanner::Location(next_loc.beg_pos, end_position()),
2413
          MessageTemplate::kInvalidDestructuringTarget);
2414

2415
      FunctionKind kind = MethodKindFor(function_flags);
2416

2417
      ExpressionT value = impl()->ParseFunctionLiteral(
2418
          name, scanner()->location(), kSkipFunctionNameCheck, kind,
2419
          next_loc.beg_pos, FunctionLiteral::kAccessorOrMethod, language_mode(),
2420
          nullptr);
2421

2422
      ObjectLiteralPropertyT result = factory()->NewObjectLiteralProperty(
2423
          name_expression, value, ObjectLiteralProperty::COMPUTED,
2424
          prop_info->is_computed_name);
2425 2426
      impl()->SetFunctionNameFromPropertyName(result, name);
      return result;
2427
    }
2428

2429 2430
    case ParsePropertyKind::kAccessorGetter:
    case ParsePropertyKind::kAccessorSetter: {
2431
      DCHECK_EQ(function_flags, ParseFunctionFlag::kIsNormal);
2432
      bool is_get = kind == ParsePropertyKind::kAccessorGetter;
2433

2434
      expression_scope()->RecordPatternError(
2435
          Scanner::Location(next_loc.beg_pos, end_position()),
2436 2437
          MessageTemplate::kInvalidDestructuringTarget);

2438
      if (!prop_info->is_computed_name) {
2439 2440 2441
        // 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.
2442
        name_expression =
2443
            factory()->NewStringLiteral(name, name_expression->position());
2444
      }
2445

2446 2447 2448
      FunctionKind kind = is_get ? FunctionKind::kGetterFunction
                                 : FunctionKind::kSetterFunction;

2449 2450
      FunctionLiteralT value = impl()->ParseFunctionLiteral(
          name, scanner()->location(), kSkipFunctionNameCheck, kind,
2451
          next_loc.beg_pos, FunctionLiteral::kAccessorOrMethod, language_mode(),
2452
          nullptr);
2453

2454 2455 2456 2457
      ObjectLiteralPropertyT result = factory()->NewObjectLiteralProperty(
          name_expression, value,
          is_get ? ObjectLiteralProperty::GETTER
                 : ObjectLiteralProperty::SETTER,
2458
          prop_info->is_computed_name);
2459 2460 2461 2462 2463
      const AstRawString* prefix =
          is_get ? ast_value_factory()->get_space_string()
                 : ast_value_factory()->set_space_string();
      impl()->SetFunctionNameFromPropertyName(result, name, prefix);
      return result;
2464
    }
2465

2466 2467
    case ParsePropertyKind::kClassField:
    case ParsePropertyKind::kNotSet:
2468
      ReportUnexpectedToken(Next());
2469
      return impl()->NullLiteralProperty();
2470
  }
2471
  UNREACHABLE();
2472 2473
}

2474
template <typename Impl>
2475
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral() {
2476 2477 2478 2479
  // ObjectLiteral ::
  // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}'

  int pos = peek_position();
2480
  ObjectPropertyListT properties(pointer_buffer());
2481
  int number_of_boilerplate_properties = 0;
2482

2483
  bool has_computed_names = false;
2484
  bool has_rest_property = false;
2485
  bool has_seen_proto = false;
2486

2487
  Consume(Token::LBRACE);
2488
  AccumulationScope accumulation_scope(expression_scope());
2489

2490
  while (!Check(Token::RBRACE)) {
2491
    FuncNameInferrerState fni_state(&fni_);
2492

2493
    ParsePropertyInfo prop_info(this, &accumulation_scope);
2494 2495 2496
    prop_info.position = PropertyPosition::kObjectLiteral;
    ObjectLiteralPropertyT property =
        ParseObjectPropertyDefinition(&prop_info, &has_seen_proto);
2497
    if (impl()->IsNull(property)) return impl()->FailureExpression();
2498

2499
    if (prop_info.is_computed_name) {
2500 2501 2502
      has_computed_names = true;
    }

2503
    if (prop_info.is_rest) {
2504 2505 2506
      has_rest_property = true;
    }

2507
    if (impl()->IsBoilerplateProperty(property) && !has_computed_names) {
2508 2509
      // Count CONSTANT or COMPUTED properties to maintain the enumeration
      // order.
2510 2511
      number_of_boilerplate_properties++;
    }
2512

2513
    properties.Add(property);
2514 2515

    if (peek() != Token::RBRACE) {
2516
      Expect(Token::COMMA);
2517 2518
    }

2519
    fni_.Infer();
2520 2521
  }

2522 2523 2524 2525 2526
  // 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.
2527
  if (has_rest_property && properties.length() > Code::kMaxArguments) {
2528
    expression_scope()->RecordPatternError(Scanner::Location(pos, position()),
2529 2530 2531
                                           MessageTemplate::kTooManyArguments);
  }

2532 2533
  return impl()->InitializeObjectLiteral(factory()->NewObjectLiteral(
      properties, number_of_boilerplate_properties, pos, has_rest_property));
2534 2535
}

2536
template <typename Impl>
2537
void ParserBase<Impl>::ParseArguments(
2538
    typename ParserBase<Impl>::ExpressionListT* args, bool* has_spread,
2539
    ParsingArrowHeadFlag maybe_arrow) {
2540 2541 2542
  // Arguments ::
  //   '(' (AssignmentExpression)*[','] ')'

2543
  *has_spread = false;
2544
  Consume(Token::LPAREN);
2545
  AccumulationScope accumulation_scope(expression_scope());
2546

2547
  while (peek() != Token::RPAREN) {
2548 2549
    int start_pos = peek_position();
    bool is_spread = Check(Token::ELLIPSIS);
nikolaos's avatar
nikolaos committed
2550
    int expr_pos = peek_position();
2551

2552
    AcceptINScope scope(this, true);
2553
    ExpressionT argument = ParseAssignmentExpressionCoverGrammar();
2554

2555 2556
    if (V8_UNLIKELY(maybe_arrow == kMaybeArrowHead)) {
      ClassifyArrowParameter(&accumulation_scope, expr_pos, argument);
2557
      if (is_spread) {
2558
        expression_scope()->RecordNonSimpleParameter();
2559
        if (argument->IsAssignment()) {
2560
          expression_scope()->RecordAsyncArrowParametersError(
2561 2562 2563
              scanner()->location(), MessageTemplate::kRestDefaultInitializer);
        }
        if (peek() == Token::COMMA) {
2564
          expression_scope()->RecordAsyncArrowParametersError(
2565 2566 2567
              scanner()->peek_location(), MessageTemplate::kParamAfterRest);
        }
      }
2568
    }
2569
    if (is_spread) {
2570
      *has_spread = true;
nikolaos's avatar
nikolaos committed
2571
      argument = factory()->NewSpread(argument, start_pos, expr_pos);
2572
    }
2573
    args->Add(argument);
2574
    if (!Check(Token::COMMA)) break;
2575
  }
2576

2577
  if (args->length() > Code::kMaxArguments) {
2578
    ReportMessage(MessageTemplate::kTooManyArguments);
2579
    return;
2580 2581
  }

2582
  Scanner::Location location = scanner_->location();
2583
  if (!Check(Token::RPAREN)) {
2584
    impl()->ReportMessageAt(location, MessageTemplate::kUnterminatedArgList);
2585 2586 2587 2588
  }
}

// Precedence = 2
2589 2590
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
2591
ParserBase<Impl>::ParseAssignmentExpressionCoverGrammar() {
2592 2593 2594 2595 2596 2597 2598 2599
  // AssignmentExpression ::
  //   ConditionalExpression
  //   ArrowFunction
  //   YieldExpression
  //   LeftHandSideExpression AssignmentOperator AssignmentExpression
  int lhs_beg_pos = peek_position();

  if (peek() == Token::YIELD && is_generator()) {
2600
    return ParseYieldExpression();
2601 2602
  }

2603
  FuncNameInferrerState fni_state(&fni_);
2604

2605 2606
  DCHECK_IMPLIES(!has_error(), next_arrow_function_info_.HasInitialState());

2607
  ExpressionT expression = ParseConditionalExpression();
2608

2609 2610
  Token::Value op = peek();

2611
  if (!Token::IsArrowOrAssignmentOp(op)) return expression;
2612 2613 2614

  // Arrow functions.
  if (V8_UNLIKELY(op == Token::ARROW)) {
2615
    Scanner::Location loc(lhs_beg_pos, end_position());
2616 2617 2618 2619 2620 2621 2622

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

2624 2625
    DeclarationScope* scope = next_arrow_function_info_.scope;
    scope->set_start_position(lhs_beg_pos);
2626

2627
    FormalParametersT parameters(scope);
2628 2629 2630
    parameters.set_strict_parameter_error(
        next_arrow_function_info_.strict_parameter_error_location,
        next_arrow_function_info_.strict_parameter_error_message);
2631
    parameters.is_simple = scope->has_simple_parameters();
2632
    next_arrow_function_info_.Reset();
2633

2634
    impl()->DeclareArrowFunctionFormalParameters(&parameters, expression, loc);
2635

2636
    expression = ParseArrowFunctionLiteral(parameters);
2637

2638 2639 2640
    return expression;
  }

2641
  if (V8_LIKELY(impl()->IsAssignableIdentifier(expression))) {
2642 2643 2644 2645 2646
    if (expression->is_parenthesized()) {
      expression_scope()->RecordDeclarationError(
          Scanner::Location(lhs_beg_pos, end_position()),
          MessageTemplate::kInvalidDestructuringTarget);
    }
2647
    expression_scope()->MarkIdentifierAsAssigned();
2648 2649 2650 2651
  } else if (expression->IsProperty()) {
    expression_scope()->RecordDeclarationError(
        Scanner::Location(lhs_beg_pos, end_position()),
        MessageTemplate::kInvalidPropertyBindingPattern);
2652 2653
  } else if (expression->IsPattern() && op == Token::ASSIGN) {
    // Destructuring assignmment.
2654
    if (expression->is_parenthesized()) {
2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667
      Scanner::Location loc(lhs_beg_pos, end_position());
      if (expression_scope()->IsCertainlyDeclaration()) {
        impl()->ReportMessageAt(loc,
                                MessageTemplate::kInvalidDestructuringTarget);
      } else {
        // Reference Error if LHS is neither object literal nor an array literal
        // (Parenthesized literals are
        // CoverParenthesizedExpressionAndArrowParameterList).
        // #sec-assignment-operators-static-semantics-early-errors
        impl()->ReportMessageAt(loc, MessageTemplate::kInvalidLhsInAssignment,
                                static_cast<const char*>(nullptr),
                                kReferenceError);
      }
2668
    }
2669 2670
    expression_scope()->ValidateAsPattern(expression, lhs_beg_pos,
                                          end_position());
2671
  } else {
2672 2673 2674 2675
    DCHECK(!IsValidReferenceExpression(expression));
    expression = RewriteInvalidReferenceExpression(
        expression, lhs_beg_pos, end_position(),
        MessageTemplate::kInvalidLhsInAssignment);
2676
  }
2677

2678
  Consume(op);
2679
  int op_position = position();
2680

2681
  ExpressionT right = ParseAssignmentExpression();
2682

2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699
  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();

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

2701
    impl()->SetFunctionNameFromIdentifierRef(right, expression);
2702
  } else {
2703 2704
    expression_scope()->RecordPatternError(
        Scanner::Location(lhs_beg_pos, end_position()),
2705
        MessageTemplate::kInvalidDestructuringTarget);
2706
    fni_.RemoveLastFunction();
2707 2708
  }

2709
  return factory()->NewAssignment(op, expression, right, op_position);
2710 2711
}

2712
template <typename Impl>
2713 2714
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseYieldExpression() {
2715 2716 2717
  // YieldExpression ::
  //   'yield' ([no line terminator] '*'? AssignmentExpression)?
  int pos = peek_position();
2718
  expression_scope()->RecordParameterInitializerError(
2719
      scanner()->peek_location(), MessageTemplate::kYieldInParameter);
2720
  Consume(Token::YIELD);
2721 2722 2723
  if (V8_UNLIKELY(scanner()->literal_contains_escapes())) {
    impl()->ReportUnexpectedToken(Token::ESCAPED_KEYWORD);
  }
2724 2725 2726

  CheckStackOverflow();

2727
  // The following initialization is necessary.
2728
  ExpressionT expression = impl()->NullExpression();
2729
  bool delegating = false;  // yield*
2730
  if (!scanner()->HasLineTerminatorBeforeNext()) {
2731
    if (Check(Token::MUL)) delegating = true;
2732 2733 2734 2735 2736 2737 2738 2739
    switch (peek()) {
      case Token::EOS:
      case Token::SEMICOLON:
      case Token::RBRACE:
      case Token::RBRACK:
      case Token::RPAREN:
      case Token::COLON:
      case Token::COMMA:
2740
      case Token::IN:
2741 2742 2743
        // 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
2744 2745
        // a regular yield, given only one look-ahead token.
        if (!delegating) break;
2746
        // Delegating yields require an RHS; fall through.
2747
        V8_FALLTHROUGH;
2748
      default:
2749
        expression = ParseAssignmentExpressionCoverGrammar();
2750 2751 2752
        break;
    }
  }
2753 2754

  if (delegating) {
2755 2756
    ExpressionT yieldstar = factory()->NewYieldStar(expression, pos);
    impl()->RecordSuspendSourceRange(yieldstar, PositionAfterSemicolon());
2757 2758
    function_state_->AddSuspend();
    if (IsAsyncGeneratorFunction(function_state_->kind())) {
2759 2760
      // return, iterator_close and delegated_iterator_output suspend ids.
      function_state_->AddSuspend();
2761 2762 2763
      function_state_->AddSuspend();
      function_state_->AddSuspend();
    }
2764
    return yieldstar;
2765
  }
2766

2767 2768
  // Hackily disambiguate o from o.next and o [Symbol.iterator]().
  // TODO(verwaest): Come up with a better solution.
2769 2770
  ExpressionT yield =
      factory()->NewYield(expression, pos, Suspend::kOnExceptionThrow);
2771
  impl()->RecordSuspendSourceRange(yield, PositionAfterSemicolon());
2772
  function_state_->AddSuspend();
2773 2774 2775 2776
  return yield;
}

// Precedence = 3
2777 2778
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
2779
ParserBase<Impl>::ParseConditionalExpression() {
2780 2781 2782 2783 2784 2785
  // ConditionalExpression ::
  //   LogicalOrExpression
  //   LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression

  int pos = peek_position();
  // We start using the binary expression parser for prec >= 4 only!
2786
  ExpressionT expression = ParseBinaryExpression(4);
2787
  return peek() == Token::CONDITIONAL
2788
             ? ParseConditionalContinuation(expression, pos)
2789
             : expression;
2790 2791 2792 2793 2794
}

template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseConditionalContinuation(ExpressionT expression,
2795
                                               int pos) {
2796
  SourceRange then_range, else_range;
2797 2798 2799

  ExpressionT left;
  {
2800
    SourceRangeScope range_scope(scanner(), &then_range);
2801
    Consume(Token::CONDITIONAL);
2802 2803 2804
    // In parsing the first assignment expression in conditional
    // expressions we always accept the 'in' keyword; see ECMA-262,
    // section 11.12, page 58.
2805 2806
    AcceptINScope scope(this, true);
    left = ParseAssignmentExpression();
2807 2808 2809
  }
  ExpressionT right;
  {
2810
    SourceRangeScope range_scope(scanner(), &else_range);
2811
    Expect(Token::COLON);
2812
    right = ParseAssignmentExpression();
2813
  }
2814 2815 2816
  ExpressionT expr = factory()->NewConditional(expression, left, right, pos);
  impl()->RecordConditionalSourceRange(expr, then_range, else_range);
  return expr;
2817 2818 2819
}

// Precedence >= 4
2820
template <typename Impl>
2821
typename ParserBase<Impl>::ExpressionT
2822
ParserBase<Impl>::ParseBinaryContinuation(ExpressionT x, int prec, int prec1) {
2823
  do {
2824
    // prec1 >= 4
2825
    while (Token::Precedence(peek(), accept_IN_) == prec1) {
2826 2827 2828 2829 2830 2831 2832 2833 2834 2835
      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;
2836
        y = ParseBinaryExpression(next_prec);
2837
      }
2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849

      // 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;
        }
2850 2851 2852 2853
        x = factory()->NewCompareOperation(cmp, x, y, pos);
        if (cmp != op) {
          // The comparison was negated - add a NOT.
          x = factory()->NewUnaryOperation(Token::NOT, x, pos);
2854
        }
2855 2856 2857
      } else if (!impl()->ShortcutNumericLiteralBinaryExpression(&x, y, op,
                                                                 pos) &&
                 !impl()->CollapseNaryExpression(&x, y, op, pos, right_range)) {
2858 2859
        // We have a "normal" binary operation.
        x = factory()->NewBinaryOperation(op, x, y, pos);
2860 2861 2862
        if (op == Token::OR || op == Token::AND) {
          impl()->RecordBinaryOperationSourceRange(x, right_range);
        }
2863 2864
      }
    }
2865 2866 2867 2868 2869 2870 2871 2872 2873
    --prec1;
  } while (prec1 >= prec);

  return x;
}

// Precedence >= 4
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBinaryExpression(
2874
    int prec) {
2875
  DCHECK_GE(prec, 4);
2876
  ExpressionT x = ParseUnaryExpression();
2877
  int prec1 = Token::Precedence(peek(), accept_IN_);
2878
  if (prec1 >= prec) {
2879
    return ParseBinaryContinuation(x, prec, prec1);
2880 2881 2882 2883
  }
  return x;
}

2884
template <typename Impl>
2885
typename ParserBase<Impl>::ExpressionT
2886
ParserBase<Impl>::ParseUnaryOrPrefixExpression() {
2887 2888 2889 2890 2891 2892 2893 2894
  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();
  }

2895 2896
  CheckStackOverflow();

2897
  int expression_position = peek_position();
2898
  ExpressionT expression = ParseUnaryExpression();
2899

2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911
  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();
      }

      if (impl()->IsPropertyWithPrivateFieldKey(expression)) {
        ReportMessage(MessageTemplate::kDeletePrivateField);
        return impl()->FailureExpression();
      }
2912 2913
    }

2914
    if (peek() == Token::EXP) {
2915 2916 2917
      impl()->ReportMessageAt(
          Scanner::Location(pos, peek_end_position()),
          MessageTemplate::kUnexpectedTokenUnaryExponentiation);
2918
      return impl()->FailureExpression();
2919 2920
    }

2921 2922
    // Allow the parser's implementation to rewrite the expression.
    return impl()->BuildUnaryExpression(expression, op, pos);
2923 2924
  }

2925
  DCHECK(Token::IsCountOp(op));
2926

2927
  if (V8_LIKELY(IsValidReferenceExpression(expression))) {
2928 2929 2930
    if (impl()->IsIdentifier(expression)) {
      expression_scope()->MarkIdentifierAsAssigned();
    }
2931
  } else {
2932
    expression = RewriteInvalidReferenceExpression(
2933
        expression, expression_position, end_position(),
2934 2935
        MessageTemplate::kInvalidLhsInPrefixOp);
  }
2936 2937 2938 2939 2940 2941

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

template <typename Impl>
2942 2943
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseAwaitExpression() {
2944
  expression_scope()->RecordParameterInitializerError(
2945 2946 2947 2948
      scanner()->peek_location(),
      MessageTemplate::kAwaitExpressionFormalParameter);
  int await_pos = peek_position();
  Consume(Token::AWAIT);
2949 2950 2951
  if (V8_UNLIKELY(scanner()->literal_contains_escapes())) {
    impl()->ReportUnexpectedToken(Token::ESCAPED_KEYWORD);
  }
2952

2953 2954
  CheckStackOverflow();

2955
  ExpressionT value = ParseUnaryExpression();
2956 2957 2958 2959 2960 2961 2962

  ExpressionT expr = factory()->NewAwait(value, await_pos);
  function_state_->AddSuspend();
  impl()->RecordSuspendSourceRange(expr, PositionAfterSemicolon());
  return expr;
}

2963
template <typename Impl>
2964 2965
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseUnaryExpression() {
2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976
  // UnaryExpression ::
  //   PostfixExpression
  //   'delete' UnaryExpression
  //   'void' UnaryExpression
  //   'typeof' UnaryExpression
  //   '++' UnaryExpression
  //   '--' UnaryExpression
  //   '+' UnaryExpression
  //   '-' UnaryExpression
  //   '~' UnaryExpression
  //   '!' UnaryExpression
2977
  //   [+Await] AwaitExpression[?Yield]
2978 2979

  Token::Value op = peek();
2980
  if (Token::IsUnaryOrCountOp(op)) return ParseUnaryOrPrefixExpression();
2981
  if (is_async_function() && op == Token::AWAIT) {
2982
    return ParseAwaitExpression();
2983
  }
2984
  return ParsePostfixExpression();
2985 2986
}

2987
template <typename Impl>
2988 2989
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParsePostfixExpression() {
2990 2991 2992 2993
  // PostfixExpression ::
  //   LeftHandSideExpression ('++' | '--')?

  int lhs_beg_pos = peek_position();
2994
  ExpressionT expression = ParseLeftHandSideExpression();
2995 2996 2997 2998 2999 3000
  if (V8_LIKELY(!Token::IsCountOp(peek()) ||
                scanner()->HasLineTerminatorBeforeNext())) {
    return expression;
  }
  return ParsePostfixContinuation(expression, lhs_beg_pos);
}
3001

3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParsePostfixContinuation(ExpressionT expression,
                                           int lhs_beg_pos) {
  if (V8_UNLIKELY(!IsValidReferenceExpression(expression))) {
    expression = RewriteInvalidReferenceExpression(
        expression, lhs_beg_pos, end_position(),
        MessageTemplate::kInvalidLhsInPostfixOp);
  }
  if (impl()->IsIdentifier(expression)) {
    expression_scope()->MarkIdentifierAsAssigned();
3013
  }
3014 3015 3016 3017

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

3020 3021
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
3022
ParserBase<Impl>::ParseLeftHandSideExpression() {
3023 3024 3025
  // LeftHandSideExpression ::
  //   (NewExpression | MemberExpression) ...

3026
  ExpressionT result = ParseMemberExpression();
3027
  if (!Token::IsPropertyOrCall(peek())) return result;
3028
  return ParseLeftHandSideContinuation(result);
3029
}
3030

3031 3032
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
3033
ParserBase<Impl>::ParseLeftHandSideContinuation(ExpressionT result) {
3034
  DCHECK(Token::IsPropertyOrCall(peek()));
3035 3036 3037

  if (V8_UNLIKELY(peek() == Token::LPAREN && impl()->IsIdentifier(result) &&
                  scanner()->current_token() == Token::ASYNC &&
3038 3039
                  !scanner()->HasLineTerminatorBeforeNext() &&
                  !scanner()->literal_contains_escapes())) {
3040 3041 3042
    DCHECK(impl()->IsAsync(impl()->AsIdentifier(result)));
    int pos = position();

3043 3044
    ArrowHeadParsingScope maybe_arrow(impl(),
                                      FunctionKind::kAsyncArrowFunction);
3045 3046
    Scope::Snapshot scope_snapshot(scope());

3047 3048
    ExpressionListT args(pointer_buffer());
    bool has_spread;
3049
    ParseArguments(&args, &has_spread, kMaybeArrowHead);
3050 3051
    if (V8_LIKELY(peek() == Token::ARROW)) {
      fni_.RemoveAsyncKeywordFromEnd();
3052
      next_arrow_function_info_.scope = maybe_arrow.ValidateAndCreateScope();
3053
      scope_snapshot.Reparent(next_arrow_function_info_.scope);
3054 3055 3056 3057 3058 3059
      // async () => ...
      if (!args.length()) return factory()->NewEmptyParentheses(pos);
      // async ( Arguments ) => ...
      ExpressionT result = impl()->ExpressionListToExpression(args);
      result->mark_parenthesized();
      return result;
3060 3061 3062 3063 3064 3065 3066 3067
    }

    if (has_spread) {
      result = impl()->SpreadCall(result, args, pos, Call::NOT_EVAL);
    } else {
      result = factory()->NewCall(result, args, pos, Call::NOT_EVAL);
    }

3068 3069
    maybe_arrow.ValidateExpression();

3070 3071 3072
    fni_.RemoveLastFunction();
    if (!Token::IsPropertyOrCall(peek())) return result;
  }
3073 3074

  do {
3075
    switch (peek()) {
3076
      /* Property */
3077 3078 3079
      case Token::LBRACK: {
        Consume(Token::LBRACK);
        int pos = position();
3080 3081
        AcceptINScope scope(this, true);
        ExpressionT index = ParseExpressionCoverGrammar();
3082
        result = factory()->NewProperty(result, index, pos);
3083
        Expect(Token::RBRACK);
3084 3085 3086
        break;
      }

3087 3088 3089 3090
      /* Property */
      case Token::PERIOD: {
        Consume(Token::PERIOD);
        int pos = position();
3091
        ExpressionT key = ParsePropertyOrPrivatePropertyName();
3092 3093 3094 3095 3096
        result = factory()->NewProperty(result, key, pos);
        break;
      }

      /* Call */
3097
      case Token::LPAREN: {
3098
        int pos;
3099
        if (Token::IsCallable(scanner()->current_token())) {
3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112
          // 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.
3113
          if (result->IsFunctionLiteral()) {
3114
            result->AsFunctionLiteral()->SetShouldEagerCompile();
3115 3116 3117 3118 3119
            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();
            }
3120 3121
          }
        }
3122
        bool has_spread;
3123
        ExpressionListT args(pointer_buffer());
3124
        ParseArguments(&args, &has_spread);
3125 3126 3127 3128 3129 3130 3131 3132

        // 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.
3133 3134
        Call::PossiblyEval is_possibly_eval =
            CheckPossibleEvalCall(result, scope());
3135

3136
        if (has_spread) {
3137
          result = impl()->SpreadCall(result, args, pos, is_possibly_eval);
3138
        } else {
3139
          result = factory()->NewCall(result, args, pos, is_possibly_eval);
3140 3141
        }

3142
        fni_.RemoveLastFunction();
3143 3144 3145
        break;
      }

3146
      /* Call */
3147
      default:
3148
        DCHECK(Token::IsTemplate(peek()));
3149
        result = ParseTemplateLiteral(result, position(), true);
3150 3151
        break;
    }
3152 3153
  } while (Token::IsPropertyOrCall(peek()));
  return result;
3154 3155
}

3156 3157
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
3158
ParserBase<Impl>::ParseMemberWithPresentNewPrefixesExpression() {
3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177
  // 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
3178 3179 3180
  Consume(Token::NEW);
  int new_pos = position();
  ExpressionT result;
3181 3182 3183

  CheckStackOverflow();

3184 3185
  if (peek() == Token::SUPER) {
    const bool is_new = true;
3186
    result = ParseSuperExpression(is_new);
3187 3188 3189 3190
  } else if (allow_harmony_dynamic_import() && peek() == Token::IMPORT &&
             (!allow_harmony_import_meta() || PeekAhead() == Token::LPAREN)) {
    impl()->ReportMessageAt(scanner()->peek_location(),
                            MessageTemplate::kImportCallNotNewExpression);
3191
    return impl()->FailureExpression();
3192
  } else if (peek() == Token::PERIOD) {
3193 3194
    result = ParseNewTargetExpression();
    return ParseMemberExpressionContinuation(result);
3195
  } else {
3196
    result = ParseMemberExpression();
3197 3198 3199
  }
  if (peek() == Token::LPAREN) {
    // NewExpression with arguments.
3200
    {
3201
      ExpressionListT args(pointer_buffer());
3202
      bool has_spread;
3203
      ParseArguments(&args, &has_spread);
3204

3205 3206 3207 3208 3209
      if (has_spread) {
        result = impl()->SpreadCallNew(result, args, new_pos);
      } else {
        result = factory()->NewCallNew(result, args, new_pos);
      }
3210
    }
3211
    // The expression can still continue with . or [ after the arguments.
3212
    return ParseMemberExpressionContinuation(result);
3213
  }
3214
  // NewExpression without arguments.
3215
  ExpressionListT args(pointer_buffer());
3216
  return factory()->NewCallNew(result, args, new_pos);
3217 3218
}

3219 3220
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
3221
ParserBase<Impl>::ParseFunctionExpression() {
3222 3223 3224 3225 3226 3227 3228
  Consume(Token::FUNCTION);
  int function_token_position = position();

  FunctionKind function_kind = Check(Token::MUL)
                                   ? FunctionKind::kGeneratorFunction
                                   : FunctionKind::kNormalFunction;
  IdentifierT name = impl()->NullIdentifier();
3229
  bool is_strict_reserved_name = Token::IsStrictReservedWord(peek());
3230 3231 3232 3233 3234 3235 3236
  Scanner::Location function_name_location = Scanner::Location::invalid();
  FunctionLiteral::FunctionType function_type =
      FunctionLiteral::kAnonymousExpression;
  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);
3237
    DCHECK_IMPLIES(!has_error(),
3238 3239
                   scanner()->CurrentSymbol(ast_value_factory()) ==
                       ast_value_factory()->anonymous_string());
3240
  } else if (peek_any_identifier()) {
3241
    name = ParseIdentifier(function_kind);
3242 3243 3244
    function_name_location = scanner()->location();
    function_type = FunctionLiteral::kNamedExpression;
  }
3245 3246 3247 3248 3249 3250 3251 3252 3253
  FunctionLiteralT result = impl()->ParseFunctionLiteral(
      name, function_name_location,
      is_strict_reserved_name ? kFunctionNameIsStrictReserved
                              : kFunctionNameValidityUnknown,
      function_kind, function_token_position, function_type, language_mode(),
      nullptr);
  // TODO(verwaest): FailureFunctionLiteral?
  if (impl()->IsNull(result)) return impl()->FailureExpression();
  return result;
3254 3255
}

3256
template <typename Impl>
3257 3258
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseMemberExpression() {
3259 3260 3261
  // MemberExpression ::
  //   (PrimaryExpression | FunctionLiteral | ClassLiteral)
  //     ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
3262 3263 3264 3265 3266
  //
  // CallExpression ::
  //   (SuperCall | ImportCall)
  //     ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
  //
3267
  // The '[' Expression ']' and '.' Identifier parts are parsed by
3268 3269
  // ParseMemberExpressionContinuation, and everything preceeding it is merged
  // into ParsePrimaryExpression.
3270 3271

  // Parse the initial primary or function expression.
3272
  ExpressionT result = ParsePrimaryExpression();
3273
  return ParseMemberExpressionContinuation(result);
3274 3275
}

3276
template <typename Impl>
3277 3278
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseImportExpressions() {
3279
  DCHECK(allow_harmony_dynamic_import());
3280

3281 3282
  Consume(Token::IMPORT);
  int pos = position();
3283 3284 3285
  if (allow_harmony_import_meta() && Check(Token::PERIOD)) {
    ExpectContextualKeyword(ast_value_factory()->meta_string(), "import.meta",
                            pos);
3286 3287 3288
    if (!parsing_module_) {
      impl()->ReportMessageAt(scanner()->location(),
                              MessageTemplate::kImportMetaOutsideModule);
3289
      return impl()->FailureExpression();
3290 3291
    }

3292
    return impl()->ImportMetaExpression(pos);
3293
  }
3294
  Expect(Token::LPAREN);
3295 3296 3297
  if (peek() == Token::RPAREN) {
    impl()->ReportMessageAt(scanner()->location(),
                            MessageTemplate::kImportMissingSpecifier);
3298
    return impl()->FailureExpression();
3299
  }
3300
  AcceptINScope scope(this, true);
3301
  ExpressionT arg = ParseAssignmentExpressionCoverGrammar();
3302
  Expect(Token::RPAREN);
3303

3304
  return factory()->NewImportCallExpression(arg, pos);
3305 3306
}

3307 3308
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseSuperExpression(
3309
    bool is_new) {
3310
  Consume(Token::SUPER);
3311 3312
  int pos = position();

3313
  DeclarationScope* scope = GetReceiverScope();
3314 3315 3316
  FunctionKind kind = scope->function_kind();
  if (IsConciseMethod(kind) || IsAccessorFunction(kind) ||
      IsClassConstructor(kind)) {
3317
    if (Token::IsProperty(peek())) {
3318 3319 3320 3321 3322 3323 3324
      if (peek() == Token::PERIOD && PeekAhead() == Token::PRIVATE_NAME) {
        Consume(Token::PERIOD);
        Consume(Token::PRIVATE_NAME);

        impl()->ReportMessage(MessageTemplate::kUnexpectedPrivateField);
        return impl()->FailureExpression();
      }
3325
      scope->RecordSuperPropertyUsage();
3326
      UseThis();
3327
      return impl()->NewSuperPropertyReference(pos);
3328 3329 3330
    }
    // new super() is never allowed.
    // super() is only allowed in derived constructor
3331
    if (!is_new && peek() == Token::LPAREN && IsDerivedConstructor(kind)) {
3332 3333
      // TODO(rossberg): This might not be the correct FunctionState for the
      // method here.
3334 3335
      expression_scope()->RecordThisUse();
      UseThis()->set_maybe_assigned();
3336
      return impl()->NewSuperCallReference(pos);
3337 3338 3339
    }
  }

3340 3341
  impl()->ReportMessageAt(scanner()->location(),
                          MessageTemplate::kUnexpectedSuper);
3342
  return impl()->FailureExpression();
3343 3344
}

3345 3346
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
3347
ParserBase<Impl>::ParseNewTargetExpression() {
3348
  int pos = position();
3349 3350 3351
  Consume(Token::PERIOD);
  ExpectContextualKeyword(ast_value_factory()->target_string(), "new.target",
                          pos);
3352

3353
  if (!GetReceiverScope()->is_function_scope()) {
3354 3355
    impl()->ReportMessageAt(scanner()->location(),
                            MessageTemplate::kUnexpectedNewTarget);
3356
    return impl()->FailureExpression();
3357 3358
  }

3359
  return impl()->NewTargetExpression(pos);
3360 3361
}

3362 3363
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
3364
ParserBase<Impl>::DoParseMemberExpressionContinuation(ExpressionT expression) {
3365
  DCHECK(Token::IsMember(peek()));
3366 3367
  // Parses this part of MemberExpression:
  // ('[' Expression ']' | '.' Identifier | TemplateLiteral)*
3368
  do {
3369 3370 3371 3372
    switch (peek()) {
      case Token::LBRACK: {
        Consume(Token::LBRACK);
        int pos = position();
3373 3374
        AcceptINScope scope(this, true);
        ExpressionT index = ParseExpressionCoverGrammar();
3375
        expression = factory()->NewProperty(expression, index, pos);
3376
        impl()->PushPropertyName(index);
3377
        Expect(Token::RBRACK);
3378 3379 3380 3381
        break;
      }
      case Token::PERIOD: {
        Consume(Token::PERIOD);
3382
        int pos = peek_position();
3383
        ExpressionT key = ParsePropertyOrPrivatePropertyName();
3384
        expression = factory()->NewProperty(expression, key, pos);
3385 3386
        break;
      }
3387
      default: {
3388
        DCHECK(Token::IsTemplate(peek()));
3389 3390 3391 3392 3393
        int pos;
        if (scanner()->current_token() == Token::IDENTIFIER) {
          pos = position();
        } else {
          pos = peek_position();
3394
          if (expression->IsFunctionLiteral()) {
3395 3396
            // If the tag function looks like an IIFE, set_parenthesized() to
            // force eager compilation.
3397
            expression->AsFunctionLiteral()->SetShouldEagerCompile();
3398 3399
          }
        }
3400
        expression = ParseTemplateLiteral(expression, pos, true);
3401 3402 3403
        break;
      }
    }
3404
  } while (Token::IsMember(peek()));
3405
  return expression;
3406 3407
}

3408
template <typename Impl>
3409
void ParserBase<Impl>::ParseFormalParameter(FormalParametersT* parameters) {
3410 3411
  // FormalParameter[Yield,GeneratorParameter] :
  //   BindingElement[?Yield, ?GeneratorParameter]
3412
  FuncNameInferrerState fni_state(&fni_);
3413
  int pos = peek_position();
3414
  auto declaration_it = scope()->declarations()->end();
3415
  ExpressionT pattern = ParseBindingPattern();
3416
  if (impl()->IsIdentifier(pattern)) {
3417
    ClassifyParameter(impl()->AsIdentifier(pattern), pos, end_position());
3418
  } else {
3419 3420 3421
    parameters->is_simple = false;
  }

3422
  ExpressionT initializer = impl()->NullExpression();
3423
  if (Check(Token::ASSIGN)) {
3424 3425
    parameters->is_simple = false;

3426
    if (parameters->has_rest) {
3427 3428 3429
      ReportMessage(MessageTemplate::kRestDefaultInitializer);
      return;
    }
3430

3431
    AcceptINScope accept_in_scope(this, true);
3432
    initializer = ParseAssignmentExpression();
3433
    impl()->SetFunctionNameFromIdentifierRef(initializer, pattern);
3434 3435
  }

3436 3437 3438 3439 3440 3441
  auto declaration_end = scope()->declarations()->end();
  int initializer_end = end_position();
  for (; declaration_it != declaration_end; ++declaration_it) {
    declaration_it->var()->set_initializer_position(initializer_end);
  }

3442
  impl()->AddFormalParameter(parameters, pattern, initializer, end_position(),
3443
                             parameters->has_rest);
3444 3445
}

3446
template <typename Impl>
3447
void ParserBase<Impl>::ParseFormalParameterList(FormalParametersT* parameters) {
3448
  // FormalParameters[Yield] :
3449 3450
  //   [empty]
  //   FunctionRestParameter[?Yield]
3451 3452 3453
  //   FormalParameterList[?Yield]
  //   FormalParameterList[?Yield] ,
  //   FormalParameterList[?Yield] , FunctionRestParameter[?Yield]
3454
  //
3455 3456 3457
  // FormalParameterList[Yield] :
  //   FormalParameter[?Yield]
  //   FormalParameterList[?Yield] , FormalParameter[?Yield]
3458
  ParameterParsingScope scope(impl(), parameters);
3459

3460
  DCHECK_EQ(0, parameters->arity);
3461 3462

  if (peek() != Token::RPAREN) {
3463
    while (true) {
3464 3465
      // Add one since we're going to be adding a parameter.
      if (parameters->arity + 1 > Code::kMaxArguments) {
3466 3467 3468
        ReportMessage(MessageTemplate::kTooManyParameters);
        return;
      }
3469
      parameters->has_rest = Check(Token::ELLIPSIS);
3470
      ParseFormalParameter(parameters);
3471

3472 3473 3474
      if (parameters->has_rest) {
        parameters->is_simple = false;
        if (peek() == Token::COMMA) {
3475 3476
          impl()->ReportMessageAt(scanner()->peek_location(),
                                  MessageTemplate::kParamAfterRest);
3477 3478 3479 3480 3481
          return;
        }
        break;
      }
      if (!Check(Token::COMMA)) break;
3482
      if (peek() == Token::RPAREN) {
3483 3484
        // allow the trailing comma
        break;
3485 3486 3487 3488
      }
    }
  }

3489
  impl()->DeclareFormalParameters(parameters);
3490 3491
}

3492
template <typename Impl>
3493
void ParserBase<Impl>::ParseVariableDeclarations(
3494
    VariableDeclarationContext var_context,
3495 3496
    DeclarationParsingResult* parsing_result,
    ZonePtrList<const AstRawString>* names) {
3497 3498 3499 3500 3501 3502 3503
  // VariableDeclarations ::
  //   ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
  //
  // ES6:
  // FIXME(marja, nikolaos): Add an up-to-date comment about ES6 variable
  // declaration syntax.

3504
  DCHECK_NOT_NULL(parsing_result);
3505
  parsing_result->descriptor.kind = NORMAL_VARIABLE;
3506 3507 3508 3509 3510
  parsing_result->descriptor.declaration_pos = peek_position();
  parsing_result->descriptor.initialization_pos = peek_position();

  switch (peek()) {
    case Token::VAR:
3511
      parsing_result->descriptor.mode = VariableMode::kVar;
3512 3513 3514 3515
      Consume(Token::VAR);
      break;
    case Token::CONST:
      Consume(Token::CONST);
3516
      DCHECK_NE(var_context, kStatement);
3517
      parsing_result->descriptor.mode = VariableMode::kConst;
3518 3519 3520
      break;
    case Token::LET:
      Consume(Token::LET);
3521
      DCHECK_NE(var_context, kStatement);
3522
      parsing_result->descriptor.mode = VariableMode::kLet;
3523 3524 3525 3526 3527 3528
      break;
    default:
      UNREACHABLE();  // by current callers
      break;
  }

3529 3530
  VariableDeclarationParsingScope declaration(
      impl(), parsing_result->descriptor.mode, names);
3531 3532 3533 3534 3535
  Scope* target_scope = IsLexicalVariableMode(parsing_result->descriptor.mode)
                            ? scope()
                            : scope()->GetDeclarationScope();

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

3537 3538 3539
  int bindings_start = peek_position();
  do {
    // Parse binding pattern.
3540
    FuncNameInferrerState fni_state(&fni_);
3541 3542

    int decl_pos = peek_position();
3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571

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

3573 3574
    Scanner::Location variable_loc = scanner()->location();

3575
    ExpressionT value = impl()->NullExpression();
3576
    int value_beg_pos = kNoSourcePosition;
3577
    if (Check(Token::ASSIGN)) {
3578
      DCHECK(!impl()->IsNull(pattern));
3579
      {
3580
        value_beg_pos = peek_position();
3581 3582 3583
        AcceptINScope scope(this, var_context != kForStatement);
        value = ParseAssignmentExpression();
      }
3584
      variable_loc.end_pos = end_position();
3585 3586 3587 3588 3589 3590

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

      // Don't infer if it is "a = function(){...}();"-like expression.
3591
      if (impl()->IsIdentifier(pattern)) {
3592
        if (!value->IsCall() && !value->IsCallNew()) {
3593
          fni_.Infer();
3594
        } else {
3595
          fni_.RemoveLastFunction();
3596 3597 3598 3599 3600
        }
      }

      impl()->SetFunctionNameFromIdentifierRef(value, pattern);
    } else {
3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621
#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

3622 3623
      if (var_context != kForStatement || !PeekInOrOf()) {
        // ES6 'const' and binding patterns require initializers.
3624
        if (parsing_result->descriptor.mode == VariableMode::kConst ||
3625
            impl()->IsNull(name)) {
3626
          impl()->ReportMessageAt(
3627
              Scanner::Location(decl_pos, end_position()),
3628
              MessageTemplate::kDeclarationMissingInitializer,
3629
              impl()->IsNull(name) ? "destructuring" : "const");
3630
          return;
3631 3632
        }
        // 'let x' initializes 'x' to undefined.
3633
        if (parsing_result->descriptor.mode == VariableMode::kLet) {
3634
          value = factory()->NewUndefinedLiteral(position());
3635 3636
        }
      }
3637
    }
3638

3639 3640 3641 3642
    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);
3643 3644
    }

3645 3646 3647 3648 3649
    // Patterns should be elided iff. they don't have an initializer.
    DCHECK_IMPLIES(impl()->IsNull(pattern),
                   impl()->IsNull(value) ||
                       (var_context == kForStatement && PeekInOrOf()));

3650 3651
    typename DeclarationParsingResult::Declaration decl(pattern, value);
    decl.value_beg_pos = value_beg_pos;
3652

3653
    parsing_result->declarations.push_back(decl);
3654 3655 3656
  } while (Check(Token::COMMA));

  parsing_result->bindings_loc =
3657
      Scanner::Location(bindings_start, end_position());
3658 3659
}

3660 3661
template <typename Impl>
typename ParserBase<Impl>::StatementT
3662
ParserBase<Impl>::ParseFunctionDeclaration() {
3663
  Consume(Token::FUNCTION);
3664

3665
  int pos = position();
3666
  ParseFunctionFlags flags = ParseFunctionFlag::kIsNormal;
3667
  if (Check(Token::MUL)) {
3668 3669 3670
    impl()->ReportMessageAt(
        scanner()->location(),
        MessageTemplate::kGeneratorInSingleStatementContext);
3671
    return impl()->NullStatement();
3672
  }
3673
  return ParseHoistableDeclaration(pos, flags, nullptr, false);
3674 3675
}

3676 3677 3678
template <typename Impl>
typename ParserBase<Impl>::StatementT
ParserBase<Impl>::ParseHoistableDeclaration(
3679
    ZonePtrList<const AstRawString>* names, bool default_export) {
3680
  Consume(Token::FUNCTION);
3681

3682
  int pos = position();
3683
  ParseFunctionFlags flags = ParseFunctionFlag::kIsNormal;
3684
  if (Check(Token::MUL)) {
3685
    flags |= ParseFunctionFlag::kIsGenerator;
3686
  }
3687
  return ParseHoistableDeclaration(pos, flags, names, default_export);
3688 3689 3690 3691 3692
}

template <typename Impl>
typename ParserBase<Impl>::StatementT
ParserBase<Impl>::ParseHoistableDeclaration(
3693
    int pos, ParseFunctionFlags flags, ZonePtrList<const AstRawString>* names,
3694
    bool default_export) {
3695 3696
  CheckStackOverflow();

3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707
  // 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.

3708 3709
  DCHECK_IMPLIES((flags & ParseFunctionFlag::kIsAsync) != 0,
                 (flags & ParseFunctionFlag::kIsGenerator) == 0);
3710

3711
  if ((flags & ParseFunctionFlag::kIsAsync) != 0 && Check(Token::MUL)) {
3712
    // Async generator
3713
    flags |= ParseFunctionFlag::kIsGenerator;
3714 3715
  }

3716 3717 3718
  IdentifierT name;
  FunctionNameValidity name_validity;
  IdentifierT variable_name;
3719 3720 3721 3722 3723 3724 3725 3726
  if (peek() == Token::LPAREN) {
    if (default_export) {
      impl()->GetDefaultStrings(&name, &variable_name);
      name_validity = kSkipFunctionNameCheck;
    } else {
      ReportMessage(MessageTemplate::kMissingFunctionName);
      return impl()->NullStatement();
    }
3727
  } else {
3728 3729
    bool is_strict_reserved = Token::IsStrictReservedWord(peek());
    name = ParseIdentifier();
3730 3731 3732 3733 3734
    name_validity = is_strict_reserved ? kFunctionNameIsStrictReserved
                                       : kFunctionNameValidityUnknown;
    variable_name = name;
  }

3735
  FuncNameInferrerState fni_state(&fni_);
3736
  impl()->PushEnclosingName(name);
3737

3738
  FunctionKind function_kind = FunctionKindFor(flags);
3739

3740
  FunctionLiteralT function = impl()->ParseFunctionLiteral(
3741
      name, scanner()->location(), name_validity, function_kind, pos,
3742
      FunctionLiteral::kDeclaration, language_mode(), nullptr);
3743

3744 3745 3746
  // 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 =
3747 3748 3749
      (!scope()->is_declaration_scope() || scope()->is_module_scope())
          ? VariableMode::kLet
          : VariableMode::kVar;
3750 3751
  // Async functions don't undergo sloppy mode block scoped hoisting, and don't
  // allow duplicates in a block. Both are represented by the
3752
  // sloppy_block_functions_. Don't add them to the map for async functions.
3753 3754
  // Generators are also supposed to be prohibited; currently doing this behind
  // a flag and UseCounting violations to assess web compatibility.
3755 3756 3757 3758 3759 3760 3761 3762
  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);
3763 3764
}

3765 3766
template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseClassDeclaration(
3767
    ZonePtrList<const AstRawString>* names, bool default_export) {
3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786
  // 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();
3787
  IdentifierT name = impl()->NullIdentifier();
3788
  bool is_strict_reserved = Token::IsStrictReservedWord(peek());
3789
  IdentifierT variable_name = impl()->NullIdentifier();
3790 3791 3792
  if (default_export && (peek() == Token::EXTENDS || peek() == Token::LBRACE)) {
    impl()->GetDefaultStrings(&name, &variable_name);
  } else {
3793
    name = ParseIdentifier();
3794 3795 3796
    variable_name = name;
  }

3797
  ExpressionParsingScope no_expression_scope(impl());
3798 3799
  ExpressionT value = ParseClassLiteral(name, scanner()->location(),
                                        is_strict_reserved, class_token_pos);
3800
  no_expression_scope.ValidateExpression();
3801 3802
  int end_pos = position();
  return impl()->DeclareClass(variable_name, value, names, class_token_pos,
3803
                              end_pos);
3804 3805 3806 3807 3808 3809 3810
}

// 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>
3811 3812
typename ParserBase<Impl>::StatementT
ParserBase<Impl>::ParseNativeDeclaration() {
3813
  function_state_->DisableOptimization(BailoutReason::kNativeFunctionLiteral);
3814

3815
  int pos = peek_position();
3816
  Consume(Token::FUNCTION);
3817
  // Allow "eval" or "arguments" for backward compatibility.
3818
  IdentifierT name = ParseIdentifier();
3819
  Expect(Token::LPAREN);
3820 3821
  if (peek() != Token::RPAREN) {
    do {
3822
      ParseIdentifier();
3823 3824
    } while (Check(Token::COMMA));
  }
3825 3826 3827
  Expect(Token::RPAREN);
  Expect(Token::SEMICOLON);
  return impl()->DeclareNative(name, pos);
3828 3829
}

3830 3831 3832
template <typename Impl>
typename ParserBase<Impl>::StatementT
ParserBase<Impl>::ParseAsyncFunctionDeclaration(
3833
    ZonePtrList<const AstRawString>* names, bool default_export) {
3834 3835 3836 3837
  // AsyncFunctionDeclaration ::
  //   async [no LineTerminator here] function BindingIdentifier[Await]
  //       ( FormalParameters[Await] ) { AsyncFunctionBody }
  DCHECK_EQ(scanner()->current_token(), Token::ASYNC);
3838 3839 3840
  if (V8_UNLIKELY(scanner()->literal_contains_escapes())) {
    impl()->ReportUnexpectedToken(Token::ESCAPED_KEYWORD);
  }
3841
  int pos = position();
3842 3843
  DCHECK(!scanner()->HasLineTerminatorBeforeNext());
  Consume(Token::FUNCTION);
3844
  ParseFunctionFlags flags = ParseFunctionFlag::kIsAsync;
3845
  return ParseHoistableDeclaration(pos, flags, names, default_export);
3846 3847
}

3848 3849
template <typename Impl>
void ParserBase<Impl>::ParseFunctionBody(
3850 3851
    StatementListT* body, IdentifierT function_name, int pos,
    const FormalParametersT& parameters, FunctionKind kind,
3852
    FunctionLiteral::FunctionType function_type, FunctionBodyType body_type) {
3853 3854
  FunctionBodyParsingScope body_parsing_scope(impl());

3855
  if (IsResumableFunction(kind)) impl()->PrepareGeneratorVariables();
3856 3857 3858 3859

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

3860 3861
  // Building the parameter initialization block declares the parameters.
  // TODO(verwaest): Rely on ArrowHeadParsingScope instead.
3862
  if (V8_UNLIKELY(!parameters.is_simple)) {
3863 3864 3865 3866 3867 3868 3869
    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;
3870

3871 3872 3873
    inner_scope = NewVarblockScope();
    inner_scope->set_start_position(scanner()->location().beg_pos);
  }
3874

3875
  StatementListT inner_body(pointer_buffer());
3876

3877 3878
  {
    BlockState block_state(&scope_, inner_scope);
3879

3880 3881
    if (body_type == FunctionBodyType::kExpression) {
      ExpressionT expression = ParseAssignmentExpression();
3882

3883 3884 3885
      if (IsAsyncFunction(kind)) {
        BlockT block = factory()->NewBlock(1, true);
        impl()->RewriteAsyncFunctionBody(&inner_body, block, expression);
3886
      } else {
3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908
        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.
      Token::Value closing_token = function_type == FunctionLiteral::kWrapped
                                       ? Token::EOS
                                       : Token::RBRACE;

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

3910
      if (IsDerivedConstructor(kind)) {
3911
        ExpressionParsingScope expression_scope(impl());
3912 3913
        inner_body.Add(factory()->NewReturnStatement(impl()->ThisExpression(),
                                                     kNoSourcePosition));
3914
        expression_scope.ValidateExpression();
3915
      }
3916
      Expect(closing_token);
3917
    }
3918
  }
3919

3920
  scope()->set_end_position(end_position());
3921

3922
  bool allow_duplicate_parameters = false;
3923

3924 3925
  CheckConflictingVarDeclarations(inner_scope);

3926 3927 3928 3929 3930
  if (V8_LIKELY(parameters.is_simple)) {
    DCHECK_EQ(inner_scope, function_scope);
    if (is_sloppy(function_scope->language_mode())) {
      impl()->InsertSloppyBlockFunctionVarBindings(function_scope);
    }
3931 3932
    allow_duplicate_parameters =
        is_sloppy(function_scope->language_mode()) && !IsConciseMethod(kind);
3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948
  } 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);
3949 3950 3951 3952 3953 3954
      if (!impl()->HasCheckedSyntax()) {
        const AstRawString* conflict = inner_scope->FindVariableDeclaredIn(
            function_scope, VariableMode::kLastLexicalVariableMode);
        if (conflict != nullptr) {
          impl()->ReportVarRedeclarationIn(conflict, inner_scope);
        }
3955
      }
3956
      impl()->InsertShadowingVarBindingInitializers(inner_block);
3957 3958 3959
    }
  }

3960 3961
  ValidateFormalParameters(language_mode(), parameters,
                           allow_duplicate_parameters);
3962

3963 3964 3965 3966 3967 3968 3969
  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());
  }

3970
  impl()->DeclareFunctionNameVar(function_name, function_type, function_scope);
3971 3972

  inner_body.MergeInto(body);
3973 3974
}

3975 3976 3977 3978 3979
template <typename Impl>
void ParserBase<Impl>::CheckArityRestrictions(int param_count,
                                              FunctionKind function_kind,
                                              bool has_rest,
                                              int formals_start_pos,
3980
                                              int formals_end_pos) {
3981
  if (impl()->HasCheckedSyntax()) return;
3982 3983
  if (IsGetterFunction(function_kind)) {
    if (param_count != 0) {
3984 3985 3986
      impl()->ReportMessageAt(
          Scanner::Location(formals_start_pos, formals_end_pos),
          MessageTemplate::kBadGetterArity);
3987 3988 3989
    }
  } else if (IsSetterFunction(function_kind)) {
    if (param_count != 1) {
3990 3991 3992
      impl()->ReportMessageAt(
          Scanner::Location(formals_start_pos, formals_end_pos),
          MessageTemplate::kBadSetterArity);
3993 3994
    }
    if (has_rest) {
3995 3996 3997
      impl()->ReportMessageAt(
          Scanner::Location(formals_start_pos, formals_end_pos),
          MessageTemplate::kBadSetterRestParameter);
3998
    }
3999 4000 4001
  }
}

4002 4003
template <typename Impl>
bool ParserBase<Impl>::IsNextLetKeyword() {
4004
  DCHECK_EQ(Token::LET, peek());
4005 4006 4007 4008 4009 4010
  Token::Value next_next = PeekAhead();
  switch (next_next) {
    case Token::LBRACE:
    case Token::LBRACK:
    case Token::IDENTIFIER:
    case Token::STATIC:
4011 4012 4013 4014 4015
    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.
4016 4017
    case Token::YIELD:
    case Token::AWAIT:
4018 4019
    case Token::GET:
    case Token::SET:
4020
    case Token::ASYNC:
4021
      return true;
4022 4023
    case Token::FUTURE_STRICT_RESERVED_WORD:
      return is_sloppy(language_mode());
4024 4025 4026 4027 4028
    default:
      return false;
  }
}

4029 4030 4031
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseArrowFunctionLiteral(
4032
    const FormalParametersT& formal_parameters) {
4033 4034 4035 4036 4037
  const RuntimeCallCounterId counters[2][2] = {
      {RuntimeCallCounterId::kParseBackgroundArrowFunctionLiteral,
       RuntimeCallCounterId::kParseArrowFunctionLiteral},
      {RuntimeCallCounterId::kPreParseBackgroundArrowFunctionLiteral,
       RuntimeCallCounterId::kPreParseArrowFunctionLiteral}};
4038 4039
  RuntimeCallTimerScope runtime_timer(
      runtime_call_stats_,
4040
      counters[Impl::IsPreParser()][parsing_on_main_thread_]);
4041 4042
  base::ElapsedTimer timer;
  if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();
4043

4044
  DCHECK_IMPLIES(!has_error(), peek() == Token::ARROW);
4045
  if (!impl()->HasCheckedSyntax() && scanner_->HasLineTerminatorBeforeNext()) {
4046 4047 4048
    // 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.
4049
    impl()->ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW);
4050
    return impl()->FailureExpression();
4051 4052
  }

4053
  int expected_property_count = 0;
4054
  int suspend_count = 0;
4055
  int function_literal_id = GetNextFunctionLiteralId();
4056

4057
  FunctionKind kind = formal_parameters.scope->function_kind();
4058
  FunctionLiteral::EagerCompileHint eager_compile_hint =
4059
      default_eager_compile_hint_;
4060
  bool can_preparse = impl()->parse_lazily() &&
4061 4062 4063 4064
                      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 =
4065
      can_preparse && impl()->AllowsLazyParsingWithoutUnresolvedVariables();
4066
  bool has_braces = true;
4067
  ProducedPreparseData* produced_preparse_data = nullptr;
4068
  StatementListT body(pointer_buffer());
4069
  {
4070
    FunctionState function_state(&function_state_, &scope_,
4071
                                 formal_parameters.scope);
4072

4073
    Consume(Token::ARROW);
4074 4075 4076

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

4079
      if (is_lazy_top_level_function) {
4080 4081 4082
        // 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.
4083

4084 4085 4086 4087 4088 4089 4090
        // 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();
        }

4091 4092 4093
        // For arrow functions, we don't need to retrieve data about function
        // parameters.
        int dummy_num_parameters = -1;
4094
        int dummy_function_length = -1;
4095
        DCHECK_NE(kind & FunctionKind::kArrowFunction, 0);
4096
        bool did_preparse_successfully = impl()->SkipFunction(
4097
            nullptr, kind, FunctionLiteral::kAnonymousExpression,
4098
            formal_parameters.scope, &dummy_num_parameters,
4099
            &dummy_function_length, &produced_preparse_data);
4100

4101
        DCHECK_NULL(produced_preparse_data);
4102 4103

        if (did_preparse_successfully) {
4104 4105 4106
          // 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);
4107 4108 4109
        } else {
          // In case we did not sucessfully preparse the function because of an
          // unidentified error we do a full reparse to return the error.
4110 4111
          // Parse again in the outer scope, since the language mode may change.
          BlockState block_state(&scope_, scope()->outer_scope());
4112
          ExpressionT expression = ParseConditionalExpression();
4113 4114 4115
          // Reparsing the head may have caused a stack overflow.
          if (has_error()) return impl()->FailureExpression();

4116 4117 4118 4119 4120 4121 4122
          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();
4123 4124 4125 4126 4127
          impl()->DeclareArrowFunctionFormalParameters(&parameters, expression,
                                                       loc);
          next_arrow_function_info_.Reset();

          Consume(Token::ARROW);
4128
          Consume(Token::LBRACE);
4129

4130
          AcceptINScope scope(this, true);
4131
          ParseFunctionBody(&body, impl()->NullIdentifier(), kNoSourcePosition,
4132
                            parameters, kind,
4133
                            FunctionLiteral::kAnonymousExpression,
4134
                            FunctionBodyType::kBlock);
4135
          CHECK(has_error());
4136
          return impl()->FailureExpression();
4137
        }
4138
      } else {
4139
        Consume(Token::LBRACE);
4140
        AcceptINScope scope(this, true);
4141
        ParseFunctionBody(&body, impl()->NullIdentifier(), kNoSourcePosition,
4142
                          formal_parameters, kind,
4143
                          FunctionLiteral::kAnonymousExpression,
4144
                          FunctionBodyType::kBlock);
4145 4146 4147 4148
        expected_property_count = function_state.expected_property_count();
      }
    } else {
      // Single-expression body
4149
      has_braces = false;
4150
      ParseFunctionBody(&body, impl()->NullIdentifier(), kNoSourcePosition,
4151 4152
                        formal_parameters, kind,
                        FunctionLiteral::kAnonymousExpression,
4153
                        FunctionBodyType::kExpression);
4154 4155 4156
      expected_property_count = function_state.expected_property_count();
    }

4157
    formal_parameters.scope->set_end_position(end_position());
4158 4159 4160 4161

    // Validate strict mode.
    if (is_strict(language_mode())) {
      CheckStrictOctalLiteral(formal_parameters.scope->start_position(),
4162
                              end_position());
4163
    }
4164
    suspend_count = function_state.suspend_count();
4165 4166 4167
  }

  FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
4168
      impl()->EmptyIdentifierString(), formal_parameters.scope, body,
4169 4170
      expected_property_count, formal_parameters.num_parameters(),
      formal_parameters.function_length,
4171
      FunctionLiteral::kNoDuplicateParameters,
4172
      FunctionLiteral::kAnonymousExpression, eager_compile_hint,
4173
      formal_parameters.scope->start_position(), has_braces,
4174
      function_literal_id, produced_preparse_data);
4175

4176
  function_literal->set_suspend_count(suspend_count);
4177 4178 4179
  function_literal->set_function_token_position(
      formal_parameters.scope->start_position());

4180
  impl()->AddFunctionForNameInference(function_literal);
4181

4182 4183 4184 4185 4186 4187
  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";
4188 4189
    logger_->FunctionEvent(event_name, script_id(), ms, scope->start_position(),
                           scope->end_position(), name, strlen(name));
4190 4191
  }

4192 4193 4194
  return function_literal;
}

4195 4196 4197
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseClassLiteral(
    IdentifierT name, Scanner::Location class_name_location,
4198
    bool name_is_strict_reserved, int class_token_pos) {
4199
  bool is_anonymous = impl()->IsNull(name);
4200

4201
  // All parts of a ClassDeclaration and ClassExpression are strict code.
4202
  if (!impl()->HasCheckedSyntax() && !is_anonymous) {
4203 4204 4205
    if (name_is_strict_reserved) {
      impl()->ReportMessageAt(class_name_location,
                              MessageTemplate::kUnexpectedStrictReserved);
4206
      return impl()->FailureExpression();
4207 4208 4209 4210
    }
    if (impl()->IsEvalOrArguments(name)) {
      impl()->ReportMessageAt(class_name_location,
                              MessageTemplate::kStrictEvalArguments);
4211
      return impl()->FailureExpression();
4212
    }
4213 4214
  }

4215 4216
  ClassScope* class_scope = NewClassScope(scope());
  BlockState block_state(&scope_, class_scope);
4217
  RaiseLanguageMode(LanguageMode::kStrict);
4218 4219

  ClassInfo class_info(this);
4220
  class_info.is_anonymous = is_anonymous;
4221
  impl()->DeclareClassVariable(name, &class_info, class_token_pos);
4222

4223
  scope()->set_start_position(end_position());
4224
  if (Check(Token::EXTENDS)) {
4225
    FuncNameInferrerState fni_state(&fni_);
4226
    ExpressionParsingScope scope(impl());
4227
    class_info.extends = ParseLeftHandSideExpression();
4228
    scope.ValidateExpression();
4229 4230
  }

4231
  Expect(Token::LBRACE);
4232

4233
  const bool has_extends = !impl()->IsNull(class_info.extends);
4234 4235
  while (peek() != Token::RBRACE) {
    if (Check(Token::SEMICOLON)) continue;
4236
    FuncNameInferrerState fni_state(&fni_);
4237 4238 4239
    // If we haven't seen the constructor yet, it potentially is the next
    // property.
    bool is_constructor = !class_info.has_seen_constructor;
4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250
    ParsePropertyInfo prop_info(this);
    prop_info.position = PropertyPosition::kClassLiteral;
    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) {
4251 4252
      class_info.has_static_computed_names = true;
    }
4253
    is_constructor &= class_info.has_seen_constructor;
4254

4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268
    bool is_field = property_kind == ClassLiteralProperty::FIELD;

    if (V8_UNLIKELY(prop_info.is_private)) {
      DCHECK(!is_constructor);
      class_info.requires_brand |= !is_field;
      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);
4269 4270 4271
      if (prop_info.is_computed_name) {
        class_info.computed_field_count++;
      }
4272 4273 4274 4275 4276
      impl()->DeclarePublicClassField(class_scope, property,
                                      prop_info.is_static,
                                      prop_info.is_computed_name, &class_info);
      impl()->InferFunctionName();
      continue;
4277
    }
4278 4279 4280

    impl()->DeclarePublicClassMethod(name, property, is_constructor,
                                     &class_info);
4281 4282 4283
    impl()->InferFunctionName();
  }

4284
  Expect(Token::RBRACE);
4285
  int end_pos = end_position();
4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296
  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,
                            unresolvable->raw_name(), kSyntaxError);
    return impl()->FailureExpression();
  }

4297 4298 4299 4300
  if (class_info.requires_brand) {
    class_scope->DeclareBrandVariable(ast_value_factory(), kNoSourcePosition);
  }

4301
  return impl()->RewriteClassLiteral(class_scope, name, &class_info,
4302
                                     class_token_pos, end_pos);
4303 4304
}

4305
template <typename Impl>
4306
void ParserBase<Impl>::ParseAsyncFunctionBody(Scope* scope,
4307
                                              StatementListT* body) {
4308
  BlockT block = impl()->NullBlock();
4309 4310 4311 4312 4313
  {
    StatementListT statements(pointer_buffer());
    ParseStatementList(&statements, Token::RBRACE);
    block = factory()->NewBlock(true, statements);
  }
4314
  impl()->RewriteAsyncFunctionBody(
4315
      body, block, factory()->NewUndefinedLiteral(kNoSourcePosition));
4316
  scope->set_end_position(end_position());
4317 4318 4319 4320
}

template <typename Impl>
typename ParserBase<Impl>::ExpressionT
4321
ParserBase<Impl>::ParseAsyncFunctionLiteral() {
4322 4323 4324 4325 4326 4327 4328
  // 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);
4329 4330 4331
  if (V8_UNLIKELY(scanner()->literal_contains_escapes())) {
    impl()->ReportUnexpectedToken(Token::ESCAPED_KEYWORD);
  }
4332
  int pos = position();
4333
  Consume(Token::FUNCTION);
4334
  IdentifierT name = impl()->NullIdentifier();
4335 4336
  FunctionLiteral::FunctionType type = FunctionLiteral::kAnonymousExpression;

4337 4338 4339
  ParseFunctionFlags flags = ParseFunctionFlag::kIsAsync;
  if (Check(Token::MUL)) flags |= ParseFunctionFlag::kIsGenerator;
  const FunctionKind kind = FunctionKindFor(flags);
4340
  bool is_strict_reserved = Token::IsStrictReservedWord(peek());
4341

4342 4343 4344
  if (impl()->ParsingDynamicFunctionDeclaration()) {
    // We don't want dynamic functions to actually declare their name
    // "anonymous". We just want that name in the toString().
4345 4346 4347

    // Consuming token we did not peek yet, which could lead to a ILLEGAL token
    // in the case of a stackoverflow.
4348 4349
    Consume(Token::IDENTIFIER);
    DCHECK_IMPLIES(!has_error(),
4350 4351
                   scanner()->CurrentSymbol(ast_value_factory()) ==
                       ast_value_factory()->anonymous_string());
4352
  } else if (peek_any_identifier()) {
4353
    type = FunctionLiteral::kNamedExpression;
4354
    name = ParseIdentifier(kind);
4355
  }
4356
  FunctionLiteralT result = impl()->ParseFunctionLiteral(
4357 4358 4359
      name, scanner()->location(),
      is_strict_reserved ? kFunctionNameIsStrictReserved
                         : kFunctionNameValidityUnknown,
4360
      kind, pos, type, language_mode(), nullptr);
4361 4362
  if (impl()->IsNull(result)) return impl()->FailureExpression();
  return result;
4363 4364
}

4365 4366
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral(
4367
    ExpressionT tag, int start, bool tagged) {
4368 4369 4370 4371 4372 4373 4374 4375 4376 4377
  // 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.
4378
  DCHECK(peek() == Token::TEMPLATE_SPAN || peek() == Token::TEMPLATE_TAIL);
4379

4380 4381 4382 4383 4384 4385
  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);
  }

4386
  bool forbid_illegal_escapes = !tagged;
4387

4388 4389 4390 4391 4392 4393
  // 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();
4394
    typename Impl::TemplateLiteralState ts = impl()->OpenTemplateLiteral(pos);
4395
    bool is_valid = CheckTemplateEscapes(forbid_illegal_escapes);
4396
    impl()->AddTemplateSpan(&ts, is_valid, true);
4397
    return impl()->CloseTemplateLiteral(&ts, start, tag);
4398 4399 4400 4401
  }

  Consume(Token::TEMPLATE_SPAN);
  int pos = position();
4402
  typename Impl::TemplateLiteralState ts = impl()->OpenTemplateLiteral(pos);
4403
  bool is_valid = CheckTemplateEscapes(forbid_illegal_escapes);
4404
  impl()->AddTemplateSpan(&ts, is_valid, false);
4405 4406 4407 4408 4409 4410 4411 4412 4413 4414
  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();
4415 4416
    AcceptINScope scope(this, true);
    ExpressionT expression = ParseExpressionCoverGrammar();
4417
    impl()->AddTemplateExpression(&ts, expression);
4418 4419

    if (peek() != Token::RBRACE) {
4420 4421
      impl()->ReportMessageAt(Scanner::Location(expr_pos, peek_position()),
                              MessageTemplate::kUnterminatedTemplateExpr);
4422
      return impl()->FailureExpression();
4423 4424 4425 4426 4427 4428 4429 4430
    }

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

4431
    bool is_valid = CheckTemplateEscapes(forbid_illegal_escapes);
4432
    impl()->AddTemplateSpan(&ts, is_valid, next == Token::TEMPLATE_TAIL);
4433 4434
  } while (next == Token::TEMPLATE_SPAN);

4435
  DCHECK_IMPLIES(!has_error(), next == Token::TEMPLATE_TAIL);
4436
  // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral.
4437
  return impl()->CloseTemplateLiteral(&ts, start, tag);
4438 4439
}

4440 4441
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
4442 4443 4444 4445 4446
ParserBase<Impl>::RewriteInvalidReferenceExpression(ExpressionT expression,
                                                    int beg_pos, int end_pos,
                                                    MessageTemplate message,
                                                    ParseErrorType type) {
  DCHECK(!IsValidReferenceExpression(expression));
4447 4448 4449
  if (impl()->IsIdentifier(expression)) {
    DCHECK(is_strict(language_mode()));
    DCHECK(impl()->IsEvalOrArguments(impl()->AsIdentifier(expression)));
4450

4451 4452
    ReportMessageAt(Scanner::Location(beg_pos, end_pos),
                    MessageTemplate::kStrictEvalArguments, kSyntaxError);
4453
    return impl()->FailureExpression();
4454
  }
4455
  if (expression->IsCall() && !expression->AsCall()->is_tagged_template()) {
4456 4457 4458
    expression_scope()->RecordPatternError(
        Scanner::Location(beg_pos, end_pos),
        MessageTemplate::kInvalidDestructuringTarget);
4459
    // If it is a call, make it a runtime error for legacy web compatibility.
4460
    // Bug: https://bugs.chromium.org/p/v8/issues/detail?id=4480
4461
    // Rewrite `expr' to `expr[throw ReferenceError]'.
4462 4463 4464 4465
    impl()->CountUsage(
        is_strict(language_mode())
            ? v8::Isolate::kAssigmentExpressionLHSIsCallInStrict
            : v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy);
4466
    ExpressionT error = impl()->NewThrowReferenceError(message, beg_pos);
4467
    return factory()->NewProperty(expression, error, beg_pos);
4468
  }
4469
  ReportMessageAt(Scanner::Location(beg_pos, end_pos), message, type);
4470
  return impl()->FailureExpression();
4471 4472
}

4473
template <typename Impl>
4474 4475 4476 4477
void ParserBase<Impl>::ClassifyParameter(IdentifierT parameter, int begin,
                                         int end) {
  if (impl()->IsEvalOrArguments(parameter)) {
    expression_scope()->RecordStrictModeParameterError(
4478 4479 4480 4481 4482
        Scanner::Location(begin, end), MessageTemplate::kStrictEvalArguments);
  }
}

template <typename Impl>
4483 4484 4485 4486 4487 4488 4489 4490 4491
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()),
4492
        MessageTemplate::kInvalidDestructuringTarget);
4493 4494 4495
  } else if (impl()->IsIdentifier(parameter)) {
    ClassifyParameter(impl()->AsIdentifier(parameter), position,
                      end_position());
4496
  } else {
4497
    expression_scope()->RecordNonSimpleParameter();
4498 4499 4500
  }
}

4501 4502
template <typename Impl>
bool ParserBase<Impl>::IsValidReferenceExpression(ExpressionT expression) {
4503 4504 4505 4506 4507 4508 4509
  return IsAssignableIdentifier(expression) || expression->IsProperty();
}

template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParsePossibleDestructuringSubPattern(
    AccumulationScope* scope) {
4510
  if (scope) scope->Accumulate();
4511 4512
  int begin = peek_position();
  ExpressionT result = ParseAssignmentExpressionCoverGrammar();
4513

4514
  if (IsValidReferenceExpression(result)) {
4515 4516 4517 4518
    // 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.
4519
    if (impl()->IsIdentifier(result)) {
4520 4521 4522 4523 4524
      if (result->is_parenthesized()) {
        expression_scope()->RecordDeclarationError(
            Scanner::Location(begin, end_position()),
            MessageTemplate::kInvalidDestructuringTarget);
      }
4525 4526
      IdentifierT identifier = impl()->AsIdentifier(result);
      ClassifyParameter(identifier, begin, end_position());
4527 4528 4529 4530 4531 4532
    } else {
      DCHECK(result->IsProperty());
      expression_scope()->RecordDeclarationError(
          Scanner::Location(begin, end_position()),
          MessageTemplate::kInvalidPropertyBindingPattern);
      if (scope != nullptr) scope->ValidateExpression();
4533
    }
4534 4535
  } else if (result->is_parenthesized() ||
             (!result->IsPattern() && !result->IsAssignment())) {
4536
    expression_scope()->RecordPatternError(
4537
        Scanner::Location(begin, end_position()),
4538
        MessageTemplate::kInvalidDestructuringTarget);
4539
  }
4540 4541

  return result;
4542 4543
}

4544
template <typename Impl>
4545
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseV8Intrinsic() {
4546 4547 4548 4549
  // CallRuntime ::
  //   '%' Identifier Arguments

  int pos = peek_position();
4550
  Consume(Token::MOD);
4551
  // Allow "eval" or "arguments" for backward compatibility.
4552
  IdentifierT name = ParseIdentifier();
4553 4554
  if (peek() != Token::LPAREN) {
    impl()->ReportUnexpectedToken(peek());
4555
    return impl()->FailureExpression();
4556
  }
4557
  bool has_spread;
4558
  ExpressionListT args(pointer_buffer());
4559
  ParseArguments(&args, &has_spread);
4560

4561 4562 4563
  if (has_spread) {
    ReportMessageAt(Scanner::Location(pos, position()),
                    MessageTemplate::kIntrinsicWithSpread, kSyntaxError);
4564
    return impl()->FailureExpression();
4565
  }
4566

4567
  return impl()->NewV8Intrinsic(name, args, pos);
4568 4569
}

4570
template <typename Impl>
4571 4572
void ParserBase<Impl>::ParseStatementList(StatementListT* body,
                                          Token::Value end_token) {
4573 4574
  // StatementList ::
  //   (StatementListItem)* <end_token>
4575
  DCHECK_NOT_NULL(body);
4576

4577 4578 4579 4580
  while (peek() == Token::STRING) {
    bool use_strict = false;
    bool use_asm = false;

4581
    Scanner::Location token_loc = scanner()->peek_location();
4582

4583
    if (scanner()->NextLiteralExactlyEquals("use strict")) {
4584
      use_strict = true;
4585
    } else if (scanner()->NextLiteralExactlyEquals("use asm")) {
4586 4587 4588 4589
      use_asm = true;
    }

    StatementT stat = ParseStatementListItem();
4590
    if (impl()->IsNull(stat)) return;
4591

4592
    body->Add(stat);
4593 4594 4595 4596

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

    if (use_strict) {
4597 4598 4599 4600 4601 4602 4603 4604 4605
      // 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");
4606
        return;
4607
      }
4608
    } else if (use_asm) {
4609 4610
      // Directive "use asm".
      impl()->SetAsmModule();
4611
    } else {
4612 4613 4614
      // Possibly an unknown directive.
      // Should not change mode, but will increment usage counters
      // as appropriate. Ditto usages below.
4615
      RaiseLanguageMode(LanguageMode::kSloppy);
4616
    }
4617
  }
4618

4619 4620 4621
  // Allocate a target stack to use for this set of source elements. This way,
  // all scripts and functions get their own target stack thus avoiding illegal
  // breaks and continues across functions.
4622
  TargetScopeT target_scope(this);
4623 4624
  while (peek() != end_token) {
    StatementT stat = ParseStatementListItem();
4625
    if (impl()->IsNull(stat)) return;
4626
    if (stat->IsEmptyStatement()) continue;
4627
    body->Add(stat);
4628 4629 4630 4631
  }
}

template <typename Impl>
4632 4633
typename ParserBase<Impl>::StatementT
ParserBase<Impl>::ParseStatementListItem() {
4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652
  // 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:
4653
      return ParseHoistableDeclaration(nullptr, false);
4654 4655
    case Token::CLASS:
      Consume(Token::CLASS);
4656
      return ParseClassDeclaration(nullptr, false);
4657 4658
    case Token::VAR:
    case Token::CONST:
4659
      return ParseVariableStatement(kStatementListItem, nullptr);
4660 4661
    case Token::LET:
      if (IsNextLetKeyword()) {
4662
        return ParseVariableStatement(kStatementListItem, nullptr);
4663 4664 4665
      }
      break;
    case Token::ASYNC:
4666
      if (PeekAhead() == Token::FUNCTION &&
4667
          !scanner()->HasLineTerminatorAfterNext()) {
4668
        Consume(Token::ASYNC);
4669
        return ParseAsyncFunctionDeclaration(nullptr, false);
4670
      }
4671
      break;
4672 4673 4674
    default:
      break;
  }
4675
  return ParseStatement(nullptr, nullptr, kAllowLabelledFunctionStatement);
4676 4677 4678 4679
}

template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseStatement(
4680
    ZonePtrList<const AstRawString>* labels,
4681
    ZonePtrList<const AstRawString>* own_labels,
4682
    AllowLabelledFunctionStatement allow_function) {
4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699
  // Statement ::
  //   Block
  //   VariableStatement
  //   EmptyStatement
  //   ExpressionStatement
  //   IfStatement
  //   IterationStatement
  //   ContinueStatement
  //   BreakStatement
  //   ReturnStatement
  //   WithStatement
  //   LabelledStatement
  //   SwitchStatement
  //   ThrowStatement
  //   TryStatement
  //   DebuggerStatement

4700 4701 4702
  // {own_labels} is always a subset of {labels}.
  DCHECK_IMPLIES(labels == nullptr, own_labels == nullptr);

4703 4704 4705 4706 4707 4708 4709 4710
  // 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:
4711
      return ParseBlock(labels);
4712 4713
    case Token::SEMICOLON:
      Next();
4714
      return factory()->EmptyStatement();
4715
    case Token::IF:
4716
      return ParseIfStatement(labels);
4717
    case Token::DO:
4718
      return ParseDoWhileStatement(labels, own_labels);
4719
    case Token::WHILE:
4720
      return ParseWhileStatement(labels, own_labels);
4721
    case Token::FOR:
4722
      if (V8_UNLIKELY(is_async_function() && PeekAhead() == Token::AWAIT)) {
4723
        return ParseForAwaitStatement(labels, own_labels);
4724
      }
4725
      return ParseForStatement(labels, own_labels);
4726
    case Token::CONTINUE:
4727
      return ParseContinueStatement();
4728
    case Token::BREAK:
4729
      return ParseBreakStatement(labels);
4730
    case Token::RETURN:
4731
      return ParseReturnStatement();
4732
    case Token::THROW:
4733
      return ParseThrowStatement();
4734
    case Token::TRY: {
4735 4736 4737 4738 4739
      // 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.
4740
      if (labels == nullptr) return ParseTryStatement();
4741 4742
      StatementListT statements(pointer_buffer());
      BlockT result = factory()->NewBlock(false, labels);
4743
      TargetT target(this, result);
4744
      StatementT statement = ParseTryStatement();
4745 4746
      statements.Add(statement);
      result->InitializeStatements(statements, zone());
4747
      return result;
4748 4749
    }
    case Token::WITH:
4750
      return ParseWithStatement(labels);
4751
    case Token::SWITCH:
4752
      return ParseSwitchStatement(labels);
4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764
    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:
4765
      return ParseDebuggerStatement();
4766
    case Token::VAR:
4767
      return ParseVariableStatement(kStatement, nullptr);
4768
    case Token::ASYNC:
4769 4770
      if (!impl()->HasCheckedSyntax() &&
          !scanner()->HasLineTerminatorAfterNext() &&
4771 4772 4773 4774 4775 4776
          PeekAhead() == Token::FUNCTION) {
        impl()->ReportMessageAt(
            scanner()->peek_location(),
            MessageTemplate::kAsyncFunctionInSingleStatementContext);
        return impl()->NullStatement();
      }
4777
      V8_FALLTHROUGH;
4778
    default:
4779
      return ParseExpressionOrLabelledStatement(labels, own_labels,
4780
                                                allow_function);
4781 4782 4783
  }
}

4784 4785
template <typename Impl>
typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseBlock(
4786
    ZonePtrList<const AstRawString>* labels) {
4787 4788 4789
  // Block ::
  //   '{' StatementList '}'

4790
  // Parse the statements and collect escaping labels.
4791 4792
  BlockT body = factory()->NewBlock(false, labels);
  StatementListT statements(pointer_buffer());
4793

4794 4795
  CheckStackOverflow();

4796
  {
4797
    BlockState block_state(zone(), &scope_);
4798
    scope()->set_start_position(peek_position());
4799
    TargetT target(this, body);
4800

4801 4802
    Expect(Token::LBRACE);

4803
    while (peek() != Token::RBRACE) {
4804
      StatementT stat = ParseStatementListItem();
4805
      if (impl()->IsNull(stat)) return body;
4806
      if (stat->IsEmptyStatement()) continue;
4807
      statements.Add(stat);
4808 4809
    }

4810
    Expect(Token::RBRACE);
4811

4812 4813
    int end_pos = end_position();
    scope()->set_end_position(end_pos);
4814

4815
    impl()->RecordBlockSourceRange(body, end_pos);
4816
    body->set_scope(scope()->FinalizeBlockScope());
4817
  }
4818 4819

  body->InitializeStatements(statements, zone_);
4820 4821 4822
  return body;
}

4823 4824
template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseScopedStatement(
4825
    ZonePtrList<const AstRawString>* labels) {
4826
  if (is_strict(language_mode()) || peek() != Token::FUNCTION) {
4827
    return ParseStatement(labels, nullptr);
4828 4829 4830
  } else {
    // Make a block around the statement for a lexical binding
    // is introduced by a FunctionDeclaration.
4831 4832
    BlockState block_state(zone(), &scope_);
    scope()->set_start_position(scanner()->location().beg_pos);
4833
    BlockT block = factory()->NewBlock(1, false);
4834
    StatementT body = ParseFunctionDeclaration();
4835
    block->statements()->Add(body, zone());
4836
    scope()->set_end_position(end_position());
4837
    block->set_scope(scope()->FinalizeBlockScope());
4838 4839 4840 4841 4842 4843 4844
    return block;
  }
}

template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseVariableStatement(
    VariableDeclarationContext var_context,
4845
    ZonePtrList<const AstRawString>* names) {
4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861
  // 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;
4862
  ParseVariableDeclarations(var_context, &parsing_result, names);
4863
  ExpectSemicolon();
4864
  return impl()->BuildInitializationBlock(&parsing_result);
4865 4866 4867
}

template <typename Impl>
4868 4869
typename ParserBase<Impl>::StatementT
ParserBase<Impl>::ParseDebuggerStatement() {
4870 4871 4872 4873 4874 4875 4876
  // 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();
4877
  Consume(Token::DEBUGGER);
4878
  ExpectSemicolon();
4879 4880 4881
  return factory()->NewDebuggerStatement(pos);
}

4882 4883 4884
template <typename Impl>
typename ParserBase<Impl>::StatementT
ParserBase<Impl>::ParseExpressionOrLabelledStatement(
4885
    ZonePtrList<const AstRawString>* labels,
4886
    ZonePtrList<const AstRawString>* own_labels,
4887
    AllowLabelledFunctionStatement allow_function) {
4888 4889 4890 4891 4892
  // ExpressionStatement | LabelledStatement ::
  //   Expression ';'
  //   Identifier ':' Statement
  //
  // ExpressionStatement[Yield] :
4893
  //   [lookahead notin {{, function, class, let [}] Expression[In, ?Yield] ;
4894 4895 4896 4897 4898 4899 4900 4901 4902 4903

  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();
4904 4905 4906 4907
    case Token::LET: {
      Token::Value next_next = PeekAhead();
      // "let" followed by either "[", "{" or an identifier means a lexical
      // declaration, which should not appear here.
4908 4909 4910
      // 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) ||
4911
           scanner_->HasLineTerminatorAfterNext())) {
4912 4913
        break;
      }
4914 4915 4916
      impl()->ReportMessageAt(scanner()->peek_location(),
                              MessageTemplate::kUnexpectedLexicalDeclaration);
      return impl()->NullStatement();
4917
    }
4918 4919 4920 4921 4922
    default:
      break;
  }

  bool starts_with_identifier = peek_any_identifier();
4923
  ExpressionT expr = ParseExpression();
4924 4925 4926 4927
  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.
4928
    impl()->DeclareLabel(&labels, &own_labels,
4929
                         impl()->AsIdentifierExpression(expr));
4930 4931
    Consume(Token::COLON);
    // ES#sec-labelled-function-declarations Labelled Function Declarations
4932 4933
    if (peek() == Token::FUNCTION && is_sloppy(language_mode()) &&
        allow_function == kAllowLabelledFunctionStatement) {
4934
      return ParseFunctionDeclaration();
4935
    }
4936
    return ParseStatement(labels, own_labels, allow_function);
4937 4938 4939 4940 4941 4942
  }

  // 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 &&
4943
      !scanner()->HasLineTerminatorBeforeNext() && impl()->IsNative(expr) &&
4944
      !scanner()->literal_contains_escapes()) {
4945
    return ParseNativeDeclaration();
4946 4947 4948
  }

  // Parsed expression statement, followed by semicolon.
4949
  ExpectSemicolon();
4950
  if (expr->IsFailureExpression()) return impl()->NullStatement();
4951 4952 4953 4954 4955
  return factory()->NewExpressionStatement(expr, pos);
}

template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseIfStatement(
4956
    ZonePtrList<const AstRawString>* labels) {
4957 4958 4959 4960
  // IfStatement ::
  //   'if' '(' Expression ')' Statement ('else' Statement)?

  int pos = peek_position();
4961
  Consume(Token::IF);
4962 4963 4964
  Expect(Token::LPAREN);
  ExpressionT condition = ParseExpression();
  Expect(Token::RPAREN);
4965 4966 4967 4968 4969

  SourceRange then_range, else_range;
  StatementT then_statement = impl()->NullStatement();
  {
    SourceRangeScope range_scope(scanner(), &then_range);
4970 4971 4972 4973 4974 4975 4976
    // 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
            : new (zone()) ZonePtrList<const AstRawString>(*labels, zone());
    then_statement = ParseScopedStatement(labels_copy);
4977 4978
  }

4979 4980
  StatementT else_statement = impl()->NullStatement();
  if (Check(Token::ELSE)) {
4981
    else_statement = ParseScopedStatement(labels);
4982
    else_range = SourceRange::ContinuationOf(then_range, end_position());
4983
  } else {
4984
    else_statement = factory()->EmptyStatement();
4985
  }
4986 4987 4988 4989
  StatementT stmt =
      factory()->NewIfStatement(condition, then_statement, else_statement, pos);
  impl()->RecordIfStatementSourceRange(stmt, then_range, else_range);
  return stmt;
4990 4991 4992
}

template <typename Impl>
4993 4994
typename ParserBase<Impl>::StatementT
ParserBase<Impl>::ParseContinueStatement() {
4995 4996 4997 4998
  // ContinueStatement ::
  //   'continue' Identifier? ';'

  int pos = peek_position();
4999
  Consume(Token::CONTINUE);
5000
  IdentifierT label = impl()->NullIdentifier();
5001
  Token::Value tok = peek();
5002 5003
  if (!scanner()->HasLineTerminatorBeforeNext() &&
      !Token::IsAutoSemicolon(tok)) {
5004
    // ECMA allows "eval" or "arguments" as labels even in strict mode.
5005
    label = ParseIdentifier();
5006
  }
5007
  IterationStatementT target = impl()->LookupContinueTarget(label);
5008
  if (impl()->IsNull(target)) {
5009
    // Illegal continue statement.
5010
    MessageTemplate message = MessageTemplate::kIllegalContinue;
5011
    BreakableStatementT breakable_target = impl()->LookupBreakTarget(label);
5012
    if (impl()->IsNull(label)) {
5013
      message = MessageTemplate::kNoIterationStatement;
5014
    } else if (impl()->IsNull(breakable_target)) {
5015 5016 5017 5018 5019
      message = MessageTemplate::kUnknownLabel;
    }
    ReportMessage(message, label);
    return impl()->NullStatement();
  }
5020
  ExpectSemicolon();
5021
  StatementT stmt = factory()->NewContinueStatement(target, pos);
5022
  impl()->RecordJumpStatementSourceRange(stmt, end_position());
5023
  return stmt;
5024 5025 5026 5027
}

template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseBreakStatement(
5028
    ZonePtrList<const AstRawString>* labels) {
5029 5030 5031 5032
  // BreakStatement ::
  //   'break' Identifier? ';'

  int pos = peek_position();
5033
  Consume(Token::BREAK);
5034
  IdentifierT label = impl()->NullIdentifier();
5035
  Token::Value tok = peek();
5036 5037
  if (!scanner()->HasLineTerminatorBeforeNext() &&
      !Token::IsAutoSemicolon(tok)) {
5038
    // ECMA allows "eval" or "arguments" as labels even in strict mode.
5039
    label = ParseIdentifier();
5040 5041 5042
  }
  // Parse labeled break statements that target themselves into
  // empty statements, e.g. 'l1: l2: l3: break l2;'
5043
  if (!impl()->IsNull(label) && impl()->ContainsLabel(labels, label)) {
5044
    ExpectSemicolon();
5045
    return factory()->EmptyStatement();
5046
  }
5047
  BreakableStatementT target = impl()->LookupBreakTarget(label);
5048
  if (impl()->IsNull(target)) {
5049
    // Illegal break statement.
5050
    MessageTemplate message = MessageTemplate::kIllegalBreak;
5051
    if (!impl()->IsNull(label)) {
5052 5053 5054 5055 5056
      message = MessageTemplate::kUnknownLabel;
    }
    ReportMessage(message, label);
    return impl()->NullStatement();
  }
5057
  ExpectSemicolon();
5058
  StatementT stmt = factory()->NewBreakStatement(target, pos);
5059
  impl()->RecordJumpStatementSourceRange(stmt, end_position());
5060
  return stmt;
5061 5062 5063
}

template <typename Impl>
5064
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseReturnStatement() {
5065 5066 5067 5068 5069 5070
  // 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).
5071
  Consume(Token::RETURN);
5072 5073
  Scanner::Location loc = scanner()->location();

5074 5075 5076 5077 5078 5079 5080 5081 5082 5083
  switch (GetDeclarationScope()->scope_type()) {
    case SCRIPT_SCOPE:
    case EVAL_SCOPE:
    case MODULE_SCOPE:
      impl()->ReportMessageAt(loc, MessageTemplate::kIllegalReturn);
      return impl()->NullStatement();
    default:
      break;
  }

5084
  Token::Value tok = peek();
5085
  ExpressionT return_value = impl()->NullExpression();
5086
  if (scanner()->HasLineTerminatorBeforeNext() || Token::IsAutoSemicolon(tok)) {
5087
    if (IsDerivedConstructor(function_state_->kind())) {
5088 5089 5090
      ExpressionParsingScope expression_scope(impl());
      return_value = impl()->ThisExpression();
      expression_scope.ValidateExpression();
5091 5092
    }
  } else {
5093
    return_value = ParseExpression();
5094
  }
5095
  ExpectSemicolon();
5096

5097
  return_value = impl()->RewriteReturn(return_value, loc.beg_pos);
5098
  int continuation_pos = end_position();
5099 5100
  StatementT stmt =
      BuildReturnStatement(return_value, loc.beg_pos, continuation_pos);
5101
  impl()->RecordJumpStatementSourceRange(stmt, end_position());
5102
  return stmt;
5103 5104 5105 5106
}

template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseWithStatement(
5107
    ZonePtrList<const AstRawString>* labels) {
5108 5109 5110
  // WithStatement ::
  //   'with' '(' Expression ')' Statement

5111
  Consume(Token::WITH);
5112 5113 5114 5115 5116 5117 5118
  int pos = position();

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

5119 5120 5121
  Expect(Token::LPAREN);
  ExpressionT expr = ParseExpression();
  Expect(Token::RPAREN);
5122 5123 5124 5125

  Scope* with_scope = NewScope(WITH_SCOPE);
  StatementT body = impl()->NullStatement();
  {
5126
    BlockState block_state(&scope_, with_scope);
5127
    with_scope->set_start_position(scanner()->peek_location().beg_pos);
5128
    body = ParseStatement(labels, nullptr);
5129
    with_scope->set_end_position(end_position());
5130 5131 5132 5133
  }
  return factory()->NewWithStatement(with_scope, expr, body, pos);
}

5134 5135
template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseDoWhileStatement(
5136
    ZonePtrList<const AstRawString>* labels,
5137
    ZonePtrList<const AstRawString>* own_labels) {
5138 5139
  // DoStatement ::
  //   'do' Statement 'while' '(' Expression ')' ';'
5140 5141
  typename FunctionState::LoopScope loop_scope(function_state_);

5142 5143
  auto loop =
      factory()->NewDoWhileStatement(labels, own_labels, peek_position());
5144
  TargetT target(this, loop);
5145

5146 5147 5148
  SourceRange body_range;
  StatementT body = impl()->NullStatement();

5149
  Consume(Token::DO);
5150 5151

  CheckStackOverflow();
5152 5153
  {
    SourceRangeScope range_scope(scanner(), &body_range);
5154
    body = ParseStatement(nullptr, nullptr);
5155
  }
5156 5157
  Expect(Token::WHILE);
  Expect(Token::LPAREN);
5158

5159 5160
  ExpressionT cond = ParseExpression();
  Expect(Token::RPAREN);
5161 5162 5163 5164 5165 5166 5167

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

5168 5169 5170
  loop->Initialize(cond, body);
  impl()->RecordIterationStatementSourceRange(loop, body_range);

5171 5172 5173 5174 5175
  return loop;
}

template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseWhileStatement(
5176
    ZonePtrList<const AstRawString>* labels,
5177
    ZonePtrList<const AstRawString>* own_labels) {
5178 5179
  // WhileStatement ::
  //   'while' '(' Expression ')' Statement
5180
  typename FunctionState::LoopScope loop_scope(function_state_);
5181

5182
  auto loop = factory()->NewWhileStatement(labels, own_labels, peek_position());
5183
  TargetT target(this, loop);
5184

5185 5186 5187
  SourceRange body_range;
  StatementT body = impl()->NullStatement();

5188
  Consume(Token::WHILE);
5189 5190 5191
  Expect(Token::LPAREN);
  ExpressionT cond = ParseExpression();
  Expect(Token::RPAREN);
5192 5193
  {
    SourceRangeScope range_scope(scanner(), &body_range);
5194
    body = ParseStatement(nullptr, nullptr);
5195
  }
5196

5197 5198 5199
  loop->Initialize(cond, body);
  impl()->RecordIterationStatementSourceRange(loop, body_range);

5200 5201 5202 5203
  return loop;
}

template <typename Impl>
5204
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseThrowStatement() {
5205 5206 5207
  // ThrowStatement ::
  //   'throw' Expression ';'

5208
  Consume(Token::THROW);
5209
  int pos = position();
5210
  if (scanner()->HasLineTerminatorBeforeNext()) {
5211 5212 5213
    ReportMessage(MessageTemplate::kNewlineAfterThrow);
    return impl()->NullStatement();
  }
5214 5215
  ExpressionT exception = ParseExpression();
  ExpectSemicolon();
5216

5217
  StatementT stmt = impl()->NewThrowStatement(exception, pos);
5218
  impl()->RecordThrowSourceRange(stmt, end_position());
5219 5220

  return stmt;
5221 5222
}

5223 5224
template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseSwitchStatement(
5225
    ZonePtrList<const AstRawString>* labels) {
5226 5227 5228 5229 5230 5231 5232 5233
  // SwitchStatement ::
  //   'switch' '(' Expression ')' '{' CaseClause* '}'
  // CaseClause ::
  //   'case' Expression ':' StatementList
  //   'default' ':' StatementList

  int switch_pos = peek_position();

5234
  Consume(Token::SWITCH);
5235 5236 5237
  Expect(Token::LPAREN);
  ExpressionT tag = ParseExpression();
  Expect(Token::RPAREN);
5238

5239 5240
  auto switch_statement =
      factory()->NewSwitchStatement(labels, tag, switch_pos);
5241 5242

  {
5243
    BlockState cases_block_state(zone(), &scope_);
5244
    scope()->set_start_position(switch_pos);
5245
    scope()->SetNonlinear();
5246
    TargetT target(this, switch_statement);
5247 5248

    bool default_seen = false;
5249
    Expect(Token::LBRACE);
5250 5251
    while (peek() != Token::RBRACE) {
      // An empty label indicates the default case.
5252
      ExpressionT label = impl()->NullExpression();
5253
      StatementListT statements(pointer_buffer());
5254
      SourceRange clause_range;
5255 5256 5257
      {
        SourceRangeScope range_scope(scanner(), &clause_range);
        if (Check(Token::CASE)) {
5258
          label = ParseExpression();
5259
        } else {
5260
          Expect(Token::DEFAULT);
5261 5262 5263 5264 5265 5266
          if (default_seen) {
            ReportMessage(MessageTemplate::kMultipleDefaultsInSwitch);
            return impl()->NullStatement();
          }
          default_seen = true;
        }
5267
        Expect(Token::COLON);
5268 5269
        while (peek() != Token::CASE && peek() != Token::DEFAULT &&
               peek() != Token::RBRACE) {
5270
          StatementT stat = ParseStatementListItem();
5271
          if (impl()->IsNull(stat)) return stat;
5272
          if (stat->IsEmptyStatement()) continue;
5273
          statements.Add(stat);
5274 5275
        }
      }
5276
      auto clause = factory()->NewCaseClause(label, statements);
5277
      impl()->RecordCaseClauseSourceRange(clause, clause_range);
5278
      switch_statement->cases()->Add(clause, zone());
5279
    }
5280
    Expect(Token::RBRACE);
5281

5282 5283 5284
    int end_pos = end_position();
    scope()->set_end_position(end_pos);
    impl()->RecordSwitchStatementSourceRange(switch_statement, end_pos);
5285 5286 5287 5288 5289
    Scope* switch_scope = scope()->FinalizeBlockScope();
    if (switch_scope != nullptr) {
      return impl()->RewriteSwitchStatement(switch_statement, switch_scope);
    }
    return switch_statement;
5290 5291 5292
  }
}

5293
template <typename Impl>
5294
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseTryStatement() {
5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305
  // TryStatement ::
  //   'try' Block Catch
  //   'try' Block Finally
  //   'try' Block Catch Finally
  //
  // Catch ::
  //   'catch' '(' Identifier ')' Block
  //
  // Finally ::
  //   'finally' Block

5306
  Consume(Token::TRY);
5307 5308
  int pos = position();

5309
  BlockT try_block = ParseBlock(nullptr);
5310 5311 5312 5313 5314 5315 5316 5317

  CatchInfo catch_info(this);

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

5318 5319
  SourceRange catch_range, finally_range;

5320
  BlockT catch_block = impl()->NullBlock();
5321 5322 5323
  {
    SourceRangeScope catch_range_scope(scanner(), &catch_range);
    if (Check(Token::CATCH)) {
5324
      bool has_binding;
5325
      has_binding = Check(Token::LPAREN);
5326

5327 5328 5329
      if (has_binding) {
        catch_info.scope = NewScope(CATCH_SCOPE);
        catch_info.scope->set_start_position(scanner()->location().beg_pos);
5330

5331
        {
5332
          BlockState catch_block_state(&scope_, catch_info.scope);
5333
          StatementListT catch_statements(pointer_buffer());
5334 5335 5336 5337 5338

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

            if (peek_any_identifier()) {
5342 5343 5344 5345
              IdentifierT identifier = ParseNonRestrictedIdentifier();
              RETURN_IF_PARSE_ERROR;
              catch_info.variable = impl()->DeclareCatchVariableName(
                  catch_info.scope, identifier);
5346
            } else {
5347 5348
              catch_info.variable = catch_info.scope->DeclareCatchVariableName(
                  ast_value_factory()->dot_catch_string());
5349 5350 5351

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

5352 5353
              VariableDeclarationParsingScope destructuring(
                  impl(), VariableMode::kLet, nullptr);
5354
              catch_info.pattern = ParseBindingPattern();
5355 5356 5357 5358 5359 5360 5361 5362

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

5363 5364
              RETURN_IF_PARSE_ERROR;
              catch_statements.Add(impl()->RewriteCatchPattern(&catch_info));
5365
            }
5366

5367
            Expect(Token::RPAREN);
5368 5369 5370 5371 5372

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

            // Check for `catch(e) { let e; }` and similar errors.
5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386
            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);
                }
5387
              }
5388
            }
5389

5390
            scope()->set_end_position(end_position());
5391
            catch_block = factory()->NewBlock(false, catch_statements);
5392 5393
            catch_block->set_scope(scope()->FinalizeBlockScope());
          }
5394 5395
        }

5396
        catch_info.scope->set_end_position(end_position());
5397
      } else {
5398
        catch_block = ParseBlock(nullptr);
5399
      }
5400
    }
5401 5402
  }

5403
  BlockT finally_block = impl()->NullBlock();
5404 5405
  DCHECK(has_error() || peek() == Token::FINALLY ||
         !impl()->IsNull(catch_block));
5406
  {
5407
    SourceRangeScope range_scope(scanner(), &finally_range);
5408
    if (Check(Token::FINALLY)) {
5409
      finally_block = ParseBlock(nullptr);
5410
    }
5411 5412
  }

5413
  RETURN_IF_PARSE_ERROR;
5414 5415 5416
  return impl()->RewriteTryStatement(try_block, catch_block, catch_range,
                                     finally_block, finally_range, catch_info,
                                     pos);
5417 5418
}

5419 5420
template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForStatement(
5421
    ZonePtrList<const AstRawString>* labels,
5422
    ZonePtrList<const AstRawString>* own_labels) {
5423 5424 5425 5426 5427 5428 5429
  // 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.
5430
  typename FunctionState::LoopScope loop_scope(function_state_);
5431

5432 5433 5434
  int stmt_pos = peek_position();
  ForInfo for_info(this);

5435
  Consume(Token::FOR);
5436
  Expect(Token::LPAREN);
5437

5438 5439
  bool starts_with_let = peek() == Token::LET;
  if (peek() == Token::CONST || (starts_with_let && IsNextLetKeyword())) {
5440 5441
    // The initializer contains lexical declarations,
    // so create an in-between scope.
5442
    BlockState for_state(zone(), &scope_);
5443
    scope()->set_start_position(position());
5444

5445 5446 5447 5448 5449 5450
    // 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_);

5451 5452 5453 5454 5455
    // 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);
5456 5457
      ParseVariableDeclarations(kForStatement, &for_info.parsing_result,
                                &for_info.bound_names);
5458
    }
5459
    DCHECK(IsLexicalVariableMode(for_info.parsing_result.descriptor.mode));
5460
    for_info.position = position();
5461 5462

    if (CheckInOrOf(&for_info.mode)) {
5463
      scope()->set_is_hidden();
5464
      return ParseForEachStatementWithDeclarations(
5465
          stmt_pos, &for_info, labels, own_labels, inner_block_scope);
5466 5467
    }

5468
    Expect(Token::SEMICOLON);
5469

5470 5471 5472 5473 5474 5475 5476
    // 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);
5477 5478
      StatementT init =
          impl()->BuildInitializationBlock(&for_info.parsing_result);
5479

5480 5481 5482 5483
      result = ParseStandardForLoopWithLexicalDeclarations(
          stmt_pos, init, &for_info, labels, own_labels);
    }
    Scope* finalized = scope()->FinalizeBlockScope();
5484 5485
    DCHECK_NULL(finalized);
    USE(finalized);
5486
    return result;
5487 5488 5489
  }

  StatementT init = impl()->NullStatement();
5490
  if (peek() == Token::VAR) {
5491 5492
    ParseVariableDeclarations(kForStatement, &for_info.parsing_result,
                              &for_info.bound_names);
5493
    DCHECK_EQ(for_info.parsing_result.descriptor.mode, VariableMode::kVar);
5494 5495 5496 5497
    for_info.position = scanner()->location().beg_pos;

    if (CheckInOrOf(&for_info.mode)) {
      return ParseForEachStatementWithDeclarations(stmt_pos, &for_info, labels,
5498
                                                   own_labels, scope());
5499 5500
    }

5501
    init = impl()->BuildInitializationBlock(&for_info.parsing_result);
5502
  } else if (peek() != Token::SEMICOLON) {
5503
    // The initializer does not contain declarations.
5504 5505
    Scanner::Location next_loc = scanner()->peek_location();
    int lhs_beg_pos = next_loc.beg_pos;
5506 5507
    int lhs_end_pos;
    bool is_for_each;
5508
    ExpressionT expression;
5509

5510
    {
5511
      ExpressionParsingScope parsing_scope(impl());
5512 5513
      AcceptINScope scope(this, false);
      expression = ParseExpressionCoverGrammar();
5514 5515 5516 5517
      // Initializer is reference followed by in/of.
      lhs_end_pos = end_position();
      is_for_each = CheckInOrOf(&for_info.mode);
      if (is_for_each) {
5518 5519 5520 5521
        if (starts_with_let && for_info.mode == ForEachStatement::ITERATE) {
          impl()->ReportMessageAt(next_loc, MessageTemplate::kForOfLet);
          return impl()->NullStatement();
        }
5522 5523 5524 5525 5526 5527 5528 5529 5530
        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();
      }
5531
    }
5532

5533
    if (is_for_each) {
5534 5535
      return ParseForEachStatementWithoutDeclarations(
          stmt_pos, expression, lhs_beg_pos, lhs_end_pos, &for_info, labels,
5536
          own_labels);
5537 5538 5539 5540
    }
    // Initializer is just an expression.
    init = factory()->NewExpressionStatement(expression, lhs_beg_pos);
  }
5541

5542
  Expect(Token::SEMICOLON);
5543

5544
  // Standard 'for' loop, we have parsed the initializer at this point.
5545
  ExpressionT cond = impl()->NullExpression();
5546 5547
  StatementT next = impl()->NullStatement();
  StatementT body = impl()->NullStatement();
5548 5549 5550
  ForStatementT loop =
      ParseStandardForLoop(stmt_pos, labels, own_labels, &cond, &next, &body);
  RETURN_IF_PARSE_ERROR;
5551 5552
  loop->Initialize(init, cond, next, body);
  return loop;
5553
}
5554

5555 5556 5557
template <typename Impl>
typename ParserBase<Impl>::StatementT
ParserBase<Impl>::ParseForEachStatementWithDeclarations(
5558
    int stmt_pos, ForInfo* for_info, ZonePtrList<const AstRawString>* labels,
5559
    ZonePtrList<const AstRawString>* own_labels, Scope* inner_block_scope) {
5560
  // Just one declaration followed by in/of.
5561
  if (for_info->parsing_result.declarations.size() != 1) {
5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577
    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();
  }
5578

5579
  BlockT init_block = impl()->RewriteForVarInLegacy(*for_info);
5580

5581 5582
  auto loop = factory()->NewForEachStatement(for_info->mode, labels, own_labels,
                                             stmt_pos);
5583
  TargetT target(this, loop);
5584

5585
  ExpressionT enumerable = impl()->NullExpression();
5586
  if (for_info->mode == ForEachStatement::ITERATE) {
5587 5588
    AcceptINScope scope(this, true);
    enumerable = ParseAssignmentExpression();
5589
  } else {
5590
    enumerable = ParseExpression();
5591
  }
5592

5593
  Expect(Token::RPAREN);
5594

5595 5596
  if (IsLexicalVariableMode(for_info->parsing_result.descriptor.mode)) {
    inner_block_scope->set_start_position(position());
5597 5598
  }

5599
  ExpressionT each_variable = impl()->NullExpression();
5600
  BlockT body_block = impl()->NullBlock();
5601
  {
5602
    BlockState block_state(&scope_, inner_block_scope);
5603

5604
    SourceRange body_range;
5605 5606 5607
    StatementT body = impl()->NullStatement();
    {
      SourceRangeScope range_scope(scanner(), &body_range);
5608
      body = ParseStatement(nullptr, nullptr);
5609 5610
    }
    impl()->RecordIterationStatementSourceRange(loop, body_range);
5611

5612 5613
    impl()->DesugarBindingInForEachStatement(for_info, &body_block,
                                             &each_variable);
5614
    body_block->statements()->Add(body, zone());
5615

5616 5617 5618
    if (IsLexicalVariableMode(for_info->parsing_result.descriptor.mode)) {
      scope()->set_end_position(end_position());
      body_block->set_scope(scope()->FinalizeBlockScope());
5619
    }
5620
  }
5621

5622
  loop->Initialize(each_variable, enumerable, body_block);
5623

5624
  init_block = impl()->CreateForEachStatementTDZ(init_block, *for_info);
5625

5626
  // Parsed for-in loop w/ variable declarations.
5627
  if (!impl()->IsNull(init_block)) {
5628
    init_block->statements()->Add(loop, zone());
5629 5630 5631 5632
    if (IsLexicalVariableMode(for_info->parsing_result.descriptor.mode)) {
      scope()->set_end_position(end_position());
      init_block->set_scope(scope()->FinalizeBlockScope());
    }
5633 5634
    return init_block;
  }
5635

5636
  return loop;
5637 5638 5639 5640 5641 5642
}

template <typename Impl>
typename ParserBase<Impl>::StatementT
ParserBase<Impl>::ParseForEachStatementWithoutDeclarations(
    int stmt_pos, ExpressionT expression, int lhs_beg_pos, int lhs_end_pos,
5643
    ForInfo* for_info, ZonePtrList<const AstRawString>* labels,
5644
    ZonePtrList<const AstRawString>* own_labels) {
5645 5646
  auto loop = factory()->NewForEachStatement(for_info->mode, labels, own_labels,
                                             stmt_pos);
5647
  TargetT target(this, loop);
5648

5649
  ExpressionT enumerable = impl()->NullExpression();
5650
  if (for_info->mode == ForEachStatement::ITERATE) {
5651 5652
    AcceptINScope scope(this, true);
    enumerable = ParseAssignmentExpression();
5653
  } else {
5654
    enumerable = ParseExpression();
5655 5656
  }

5657
  Expect(Token::RPAREN);
5658

5659
  StatementT body = impl()->NullStatement();
5660
  SourceRange body_range;
5661
  {
5662
    SourceRangeScope range_scope(scanner(), &body_range);
5663
    body = ParseStatement(nullptr, nullptr);
5664
  }
5665
  impl()->RecordIterationStatementSourceRange(loop, body_range);
5666
  RETURN_IF_PARSE_ERROR;
5667 5668
  loop->Initialize(expression, enumerable, body);
  return loop;
5669 5670 5671
}

template <typename Impl>
5672
typename ParserBase<Impl>::StatementT
5673 5674
ParserBase<Impl>::ParseStandardForLoopWithLexicalDeclarations(
    int stmt_pos, StatementT init, ForInfo* for_info,
5675
    ZonePtrList<const AstRawString>* labels,
5676
    ZonePtrList<const AstRawString>* own_labels) {
5677 5678 5679
  // The condition and the next statement of the for loop must be parsed
  // in a new scope.
  Scope* inner_scope = NewScope(BLOCK_SCOPE);
5680
  ForStatementT loop = impl()->NullStatement();
5681
  ExpressionT cond = impl()->NullExpression();
5682 5683
  StatementT next = impl()->NullStatement();
  StatementT body = impl()->NullStatement();
5684
  {
5685
    BlockState block_state(&scope_, inner_scope);
5686
    scope()->set_start_position(scanner()->location().beg_pos);
5687 5688 5689
    loop =
        ParseStandardForLoop(stmt_pos, labels, own_labels, &cond, &next, &body);
    RETURN_IF_PARSE_ERROR;
5690
    scope()->set_end_position(end_position());
5691 5692
  }

5693
  scope()->set_end_position(end_position());
5694 5695 5696 5697
  if (for_info->bound_names.length() > 0 &&
      function_state_->contains_function_or_eval()) {
    scope()->set_is_hidden();
    return impl()->DesugarLexicalBindingsInForStatement(
5698
        loop, init, cond, next, body, inner_scope, *for_info);
5699 5700 5701 5702
  } else {
    inner_scope = inner_scope->FinalizeBlockScope();
    DCHECK_NULL(inner_scope);
    USE(inner_scope);
5703
  }
5704

5705
  Scope* for_scope = scope()->FinalizeBlockScope();
5706 5707 5708 5709 5710 5711 5712 5713 5714 5715 5716
  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
    //   }
    //
5717
    DCHECK(!impl()->IsNull(init));
5718
    BlockT block = factory()->NewBlock(2, false);
5719
    block->statements()->Add(init, zone());
5720 5721
    block->statements()->Add(loop, zone());
    block->set_scope(for_scope);
5722
    loop->Initialize(impl()->NullStatement(), cond, next, body);
5723 5724 5725
    return block;
  }

5726
  loop->Initialize(init, cond, next, body);
5727 5728 5729 5730 5731
  return loop;
}

template <typename Impl>
typename ParserBase<Impl>::ForStatementT ParserBase<Impl>::ParseStandardForLoop(
5732 5733
    int stmt_pos, ZonePtrList<const AstRawString>* labels,
    ZonePtrList<const AstRawString>* own_labels, ExpressionT* cond,
5734
    StatementT* next, StatementT* body) {
5735
  ForStatementT loop = factory()->NewForStatement(labels, own_labels, stmt_pos);
5736
  TargetT target(this, loop);
5737 5738

  if (peek() != Token::SEMICOLON) {
5739
    *cond = ParseExpression();
5740
  }
5741
  Expect(Token::SEMICOLON);
5742 5743

  if (peek() != Token::RPAREN) {
5744
    ExpressionT exp = ParseExpression();
5745 5746
    *next = factory()->NewExpressionStatement(exp, exp->position());
  }
5747
  Expect(Token::RPAREN);
5748 5749 5750 5751

  SourceRange body_range;
  {
    SourceRangeScope range_scope(scanner(), &body_range);
5752
    *body = ParseStatement(nullptr, nullptr);
5753
  }
5754
  impl()->RecordIterationStatementSourceRange(loop, body_range);
5755

5756
  return loop;
5757 5758
}

5759 5760
template <typename Impl>
typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForAwaitStatement(
5761
    ZonePtrList<const AstRawString>* labels,
5762
    ZonePtrList<const AstRawString>* own_labels) {
5763 5764
  // for await '(' ForDeclaration of AssignmentExpression ')'
  DCHECK(is_async_function());
5765
  typename FunctionState::LoopScope loop_scope(function_state_);
5766 5767 5768 5769 5770 5771 5772

  int stmt_pos = peek_position();

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

  // Create an in-between scope for let-bound iteration variables.
5773
  BlockState for_state(zone(), &scope_);
5774 5775 5776
  Expect(Token::FOR);
  Expect(Token::AWAIT);
  Expect(Token::LPAREN);
5777 5778
  scope()->set_start_position(scanner()->location().beg_pos);
  scope()->set_is_hidden();
5779

5780 5781 5782 5783 5784 5785
  auto loop = factory()->NewForOfStatement(labels, own_labels, stmt_pos,
                                           IteratorType::kAsync);
  // Two suspends: one for next() and one for return()
  function_state_->AddSuspend();
  function_state_->AddSuspend();

5786
  TargetT target(this, loop);
5787

5788
  ExpressionT each_variable = impl()->NullExpression();
5789 5790

  bool has_declarations = false;
5791
  Scope* inner_block_scope = NewScope(BLOCK_SCOPE);
5792

5793
  bool starts_with_let = peek() == Token::LET;
5794
  if (peek() == Token::VAR || peek() == Token::CONST ||
5795
      (starts_with_let && IsNextLetKeyword())) {
5796 5797 5798 5799 5800 5801
    // The initializer contains declarations
    // 'for' 'await' '(' ForDeclaration 'of' AssignmentExpression ')'
    //     Statement
    // 'for' 'await' '(' 'var' ForBinding 'of' AssignmentExpression ')'
    //     Statement
    has_declarations = true;
5802 5803 5804

    {
      BlockState inner_state(&scope_, inner_block_scope);
5805 5806
      ParseVariableDeclarations(kForStatement, &for_info.parsing_result,
                                &for_info.bound_names);
5807
    }
5808 5809 5810
    for_info.position = scanner()->location().beg_pos;

    // Only a single declaration is allowed in for-await-of loops
5811
    if (for_info.parsing_result.declarations.size() != 1) {
5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828
      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
5829 5830 5831 5832 5833
    if (starts_with_let) {
      impl()->ReportMessageAt(scanner()->peek_location(),
                              MessageTemplate::kForOfLet);
      return impl()->NullStatement();
    }
5834
    int lhs_beg_pos = peek_position();
5835
    BlockState inner_state(&scope_, inner_block_scope);
5836
    ExpressionParsingScope parsing_scope(impl());
5837
    ExpressionT lhs = each_variable = ParseLeftHandSideExpression();
5838
    int lhs_end_pos = end_position();
5839

5840
    if (lhs->IsPattern()) {
5841
      parsing_scope.ValidatePattern(lhs, lhs_beg_pos, lhs_end_pos);
5842
    } else {
5843 5844
      each_variable = parsing_scope.ValidateAndRewriteReference(
          lhs, lhs_beg_pos, lhs_end_pos);
5845 5846 5847
    }
  }

5848
  ExpectContextualKeyword(ast_value_factory()->of_string());
5849 5850

  const bool kAllowIn = true;
5851
  ExpressionT iterable = impl()->NullExpression();
5852 5853

  {
5854 5855
    AcceptINScope scope(this, kAllowIn);
    iterable = ParseAssignmentExpression();
5856 5857
  }

5858
  Expect(Token::RPAREN);
5859

5860
  StatementT body = impl()->NullStatement();
5861
  {
5862
    BlockState block_state(&scope_, inner_block_scope);
5863
    scope()->set_start_position(scanner()->location().beg_pos);
5864

5865
    SourceRange body_range;
5866 5867
    {
      SourceRangeScope range_scope(scanner(), &body_range);
5868
      body = ParseStatement(nullptr, nullptr);
5869 5870 5871
      scope()->set_end_position(end_position());
    }
    impl()->RecordIterationStatementSourceRange(loop, body_range);
5872 5873

    if (has_declarations) {
5874
      BlockT body_block = impl()->NullBlock();
5875 5876
      impl()->DesugarBindingInForEachStatement(&for_info, &body_block,
                                               &each_variable);
5877
      body_block->statements()->Add(body, zone());
5878
      body_block->set_scope(scope()->FinalizeBlockScope());
5879
      body = body_block;
5880
    } else {
5881
      Scope* block_scope = scope()->FinalizeBlockScope();
5882 5883 5884 5885
      DCHECK_NULL(block_scope);
      USE(block_scope);
    }
  }
5886 5887

  loop->Initialize(each_variable, iterable, body);
5888 5889 5890 5891 5892

  if (!has_declarations) {
    Scope* for_scope = scope()->FinalizeBlockScope();
    DCHECK_NULL(for_scope);
    USE(for_scope);
5893
    return loop;
5894
  }
5895

5896
  BlockT init_block =
5897
      impl()->CreateForEachStatementTDZ(impl()->NullBlock(), for_info);
5898

5899
  scope()->set_end_position(end_position());
5900
  Scope* for_scope = scope()->FinalizeBlockScope();
5901
  // Parsed for-in loop w/ variable declarations.
5902
  if (!impl()->IsNull(init_block)) {
5903
    init_block->statements()->Add(loop, zone());
5904 5905 5906 5907
    init_block->set_scope(for_scope);
    return init_block;
  }
  DCHECK_NULL(for_scope);
5908
  return loop;
5909 5910
}

5911
template <typename Impl>
5912 5913 5914 5915 5916
void ParserBase<Impl>::CheckClassMethodName(IdentifierT name,
                                            ParsePropertyKind type,
                                            ParseFunctionFlags flags,
                                            bool is_static,
                                            bool* has_seen_constructor) {
5917
  DCHECK(type == ParsePropertyKind::kMethod || IsAccessor(type));
5918

5919
  AstValueFactory* avf = ast_value_factory();
5920

5921
  if (is_static) {
5922 5923
    if (impl()->IdentifierEquals(name, avf->prototype_string())) {
      ReportMessage(MessageTemplate::kStaticPrototype);
5924 5925
      return;
    }
5926 5927 5928 5929
  } else if (impl()->IdentifierEquals(name,
                                      avf->private_constructor_string())) {
    ReportMessage(MessageTemplate::kConstructorIsPrivate);
    return;
5930
  } else if (impl()->IdentifierEquals(name, avf->constructor_string())) {
5931
    if (flags != ParseFunctionFlag::kIsNormal || IsAccessor(type)) {
5932 5933 5934 5935 5936
      MessageTemplate msg = (flags & ParseFunctionFlag::kIsGenerator) != 0
                                ? MessageTemplate::kConstructorIsGenerator
                                : (flags & ParseFunctionFlag::kIsAsync) != 0
                                      ? MessageTemplate::kConstructorIsAsync
                                      : MessageTemplate::kConstructorIsAccessor;
5937
      ReportMessage(msg);
5938 5939
      return;
    }
5940 5941
    if (*has_seen_constructor) {
      ReportMessage(MessageTemplate::kDuplicateConstructor);
5942 5943
      return;
    }
5944
    *has_seen_constructor = true;
5945 5946 5947
    return;
  }
}
5948

5949
template <typename Impl>
5950 5951 5952 5953
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);
5954 5955 5956
    return;
  }

5957 5958 5959
  if (impl()->IdentifierEquals(name, avf->constructor_string()) ||
      impl()->IdentifierEquals(name, avf->private_constructor_string())) {
    ReportMessage(MessageTemplate::kConstructorClassField);
5960 5961 5962 5963
    return;
  }
}

5964
#undef RETURN_IF_PARSE_ERROR
5965

5966 5967 5968
}  // namespace internal
}  // namespace v8

5969
#endif  // V8_PARSING_PARSER_BASE_H_