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

5 6
#ifndef V8_AST_AST_H_
#define V8_AST_AST_H_
7

8 9
#include <memory>

10 11 12
#include "src/ast/ast-value-factory.h"
#include "src/ast/modules.h"
#include "src/ast/variables.h"
13
#include "src/base/threaded-list.h"
14 15
#include "src/codegen/bailout-reason.h"
#include "src/codegen/label.h"
16
#include "src/common/globals.h"
17
#include "src/heap/factory.h"
18
#include "src/objects/elements-kind.h"
19
#include "src/objects/function-syntax-kind.h"
20
#include "src/objects/literal-objects.h"
21
#include "src/objects/smi.h"
22
#include "src/parsing/token.h"
23
#include "src/runtime/runtime.h"
24

25 26
namespace v8 {
namespace internal {
27 28 29 30 31 32 33 34 35 36 37 38 39 40

// The abstract syntax tree is an intermediate, light-weight
// representation of the parsed JavaScript code suitable for
// compilation to native code.

// Nodes are allocated in a separate zone, which allows faster
// allocation and constant-time deallocation of the entire syntax
// tree.


// ----------------------------------------------------------------------------
// Nodes of the abstract syntax tree. Only concrete classes are
// enumerated here.

arv@chromium.org's avatar
arv@chromium.org committed
41 42
#define DECLARATION_NODE_LIST(V) \
  V(VariableDeclaration)         \
43
  V(FunctionDeclaration)
44

45 46 47 48 49 50 51 52 53 54 55
#define ITERATION_NODE_LIST(V) \
  V(DoWhileStatement)          \
  V(WhileStatement)            \
  V(ForStatement)              \
  V(ForInStatement)            \
  V(ForOfStatement)

#define BREAKABLE_NODE_LIST(V) \
  V(Block)                     \
  V(SwitchStatement)

56
#define STATEMENT_NODE_LIST(V)    \
57 58
  ITERATION_NODE_LIST(V)          \
  BREAKABLE_NODE_LIST(V)          \
59 60 61 62 63 64 65 66 67 68
  V(ExpressionStatement)          \
  V(EmptyStatement)               \
  V(SloppyBlockFunctionStatement) \
  V(IfStatement)                  \
  V(ContinueStatement)            \
  V(BreakStatement)               \
  V(ReturnStatement)              \
  V(WithStatement)                \
  V(TryCatchStatement)            \
  V(TryFinallyStatement)          \
69
  V(DebuggerStatement)            \
70
  V(InitializeClassMembersStatement)
71

72 73 74 75 76
#define LITERAL_NODE_LIST(V) \
  V(RegExpLiteral)           \
  V(ObjectLiteral)           \
  V(ArrayLiteral)

arv@chromium.org's avatar
arv@chromium.org committed
77
#define EXPRESSION_NODE_LIST(V) \
78
  LITERAL_NODE_LIST(V)          \
79
  V(Assignment)                 \
80
  V(Await)                      \
arv@chromium.org's avatar
arv@chromium.org committed
81
  V(BinaryOperation)            \
82
  V(NaryOperation)              \
83 84 85 86
  V(Call)                       \
  V(CallNew)                    \
  V(CallRuntime)                \
  V(ClassLiteral)               \
arv@chromium.org's avatar
arv@chromium.org committed
87
  V(CompareOperation)           \
88 89 90
  V(CompoundAssignment)         \
  V(Conditional)                \
  V(CountOperation)             \
91
  V(EmptyParentheses)           \
92
  V(FunctionLiteral)            \
93
  V(GetTemplateObject)          \
94 95 96
  V(ImportCallExpression)       \
  V(Literal)                    \
  V(NativeFunctionLiteral)      \
97
  V(OptionalChain)              \
98 99 100 101
  V(Property)                   \
  V(Spread)                     \
  V(SuperCallReference)         \
  V(SuperPropertyReference)     \
102
  V(TemplateLiteral)            \
103
  V(ThisExpression)             \
104 105 106 107 108
  V(Throw)                      \
  V(UnaryOperation)             \
  V(VariableProxy)              \
  V(Yield)                      \
  V(YieldStar)
109

110 111
#define FAILURE_NODE_LIST(V) V(FailureExpression)

112
#define AST_NODE_LIST(V)                        \
113
  DECLARATION_NODE_LIST(V)                      \
114
  STATEMENT_NODE_LIST(V)                        \
115
  EXPRESSION_NODE_LIST(V)
116

117
// Forward declarations
118 119 120
class Isolate;
class OffThreadIsolate;

121
class AstNode;
122
class AstNodeFactory;
123
class Declaration;
124 125 126
class BreakableStatement;
class Expression;
class IterationStatement;
127
class MaterializedLiteral;
128
class NestedVariableDeclaration;
129
class ProducedPreparseData;
130
class Statement;
131

132
#define DEF_FORWARD_DECLARATION(type) class type;
133
AST_NODE_LIST(DEF_FORWARD_DECLARATION)
134
FAILURE_NODE_LIST(DEF_FORWARD_DECLARATION)
135 136
#undef DEF_FORWARD_DECLARATION

137
class AstNode: public ZoneObject {
138
 public:
139
#define DECLARE_TYPE_ENUM(type) k##type,
140 141 142 143
  enum NodeType : uint8_t {
    AST_NODE_LIST(DECLARE_TYPE_ENUM) /* , */
    FAILURE_NODE_LIST(DECLARE_TYPE_ENUM)
  };
144 145
#undef DECLARE_TYPE_ENUM

146
  void* operator new(size_t size, Zone* zone) { return zone->New(size); }
147

148
  NodeType node_type() const { return NodeTypeField::decode(bit_field_); }
149
  int position() const { return position_; }
150

151
#ifdef DEBUG
152
  void Print(Isolate* isolate);
153 154
#endif  // DEBUG

155
  // Type testing & conversion functions overridden by concrete subclasses.
156
#define DECLARE_NODE_FUNCTIONS(type) \
157 158 159
  V8_INLINE bool Is##type() const;   \
  V8_INLINE type* As##type();        \
  V8_INLINE const type* As##type() const;
160
  AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
161
  FAILURE_NODE_LIST(DECLARE_NODE_FUNCTIONS)
162
#undef DECLARE_NODE_FUNCTIONS
163

164 165
  IterationStatement* AsIterationStatement();
  MaterializedLiteral* AsMaterializedLiteral();
166

167 168 169 170 171
 private:
  // Hidden to prevent accidental usage. It would have to load the
  // current zone from the TLS.
  void* operator new(size_t size);

172
  int position_;
173
  using NodeTypeField = base::BitField<NodeType, 0, 6>;
174 175 176

 protected:
  uint32_t bit_field_;
177 178 179

  template <class T, int size>
  using NextBitField = NodeTypeField::Next<T, size>;
180 181 182

  AstNode(int position, NodeType type)
      : position_(position), bit_field_(NodeTypeField::encode(type)) {}
183 184 185
};


186
class Statement : public AstNode {
187
 protected:
188
  Statement(int position, NodeType type) : AstNode(position, type) {}
189 190 191
};


192
class Expression : public AstNode {
193
 public:
194 195 196 197 198 199 200 201 202 203 204 205
  enum Context {
    // Not assigned a context yet, or else will not be visited during
    // code generation.
    kUninitialized,
    // Evaluated for its side effects.
    kEffect,
    // Evaluated for its value (and side effects).
    kValue,
    // Evaluated for control flow (and side effects).
    kTest
  };

206
  // True iff the expression is a valid reference expression.
207
  bool IsValidReferenceExpression() const;
208

209 210 211
  // True iff the expression is a private name.
  bool IsPrivateName() const;

212
  // Helpers for ToBoolean conversion.
213 214
  bool ToBooleanIsTrue() const;
  bool ToBooleanIsFalse() const;
215

216 217 218
  // Symbols that cannot be parsed as array indices are considered property
  // names.  We do not treat symbols that can be array indexes as property
  // names because [] for string objects is handled only by keyed ICs.
219
  bool IsPropertyName() const;
220

221 222
  // True iff the expression is a class or function expression without
  // a syntactic name.
223
  bool IsAnonymousFunctionDefinition() const;
224

225 226 227 228 229 230
  // True iff the expression is a concise method definition.
  bool IsConciseMethodDefinition() const;

  // True iff the expression is an accessor function definition.
  bool IsAccessorFunctionDefinition() const;

231
  // True iff the expression is a literal represented as a smi.
232
  bool IsSmiLiteral() const;
233

234
  // True iff the expression is a literal represented as a number.
235
  V8_EXPORT_PRIVATE bool IsNumberLiteral() const;
236

237
  // True iff the expression is a string literal.
238
  bool IsStringLiteral() const;
239 240

  // True iff the expression is the null literal.
241
  bool IsNullLiteral() const;
242

243 244 245
  // True iff the expression is the hole literal.
  bool IsTheHoleLiteral() const;

246 247 248
  // True if we can prove that the expression is the undefined literal. Note
  // that this also checks for loads of the global "undefined" variable.
  bool IsUndefinedLiteral() const;
249

250 251 252 253 254 255 256 257
  // True if either null literal or undefined literal.
  inline bool IsNullOrUndefinedLiteral() const {
    return IsNullLiteral() || IsUndefinedLiteral();
  }

  // True if a literal and not null or undefined.
  bool IsLiteralButNotNullOrUndefined() const;

258 259
  bool IsCompileTimeValue();

260
  bool IsPattern() {
261
    STATIC_ASSERT(kObjectLiteral + 1 == kArrayLiteral);
262
    return base::IsInRange(node_type(), kObjectLiteral, kArrayLiteral);
263 264
  }

265 266 267 268 269 270 271 272
  bool is_parenthesized() const {
    return IsParenthesizedField::decode(bit_field_);
  }

  void mark_parenthesized() {
    bit_field_ = IsParenthesizedField::update(bit_field_, true);
  }

273 274 275 276
  void clear_parenthesized() {
    bit_field_ = IsParenthesizedField::update(bit_field_, false);
  }

277
 private:
278
  using IsParenthesizedField = AstNode::NextBitField<bool, 1>;
279

280
 protected:
281 282 283
  Expression(int pos, NodeType type) : AstNode(pos, type) {
    DCHECK(!is_parenthesized());
  }
284

285 286
  template <class T, int size>
  using NextBitField = IsParenthesizedField::Next<T, size>;
287 288
};

289 290 291 292 293 294
class FailureExpression : public Expression {
 private:
  friend class AstNodeFactory;
  FailureExpression() : Expression(kNoSourcePosition, kFailureExpression) {}
};

295 296 297
// V8's notion of BreakableStatement does not correspond to the notion of
// BreakableStatement in ECMAScript. In V8, the idea is that a
// BreakableStatement is a statement that can be the target of a break
298
// statement.
299
//
300
// Since we don't want to track a list of labels for all kinds of statements, we
301 302 303 304 305
// only declare switchs, loops, and blocks as BreakableStatements.  This means
// that we implement breaks targeting other statement forms as breaks targeting
// a substatement thereof. For instance, in "foo: if (b) { f(); break foo; }" we
// pretend that foo is the label of the inner block. That's okay because one
// can't observe the difference.
306 307
// TODO(verwaest): Reconsider this optimization now that the tracking of labels
// is done at runtime.
308
class BreakableStatement : public Statement {
309
 protected:
310
  BreakableStatement(int position, NodeType type) : Statement(position, type) {}
311 312
};

313
class Block final : public BreakableStatement {
314
 public:
315
  ZonePtrList<Statement>* statements() { return &statements_; }
316 317 318
  bool ignore_completion_value() const {
    return IgnoreCompletionField::decode(bit_field_);
  }
319
  bool is_breakable() const { return IsBreakableField::decode(bit_field_); }
320

321 322
  Scope* scope() const { return scope_; }
  void set_scope(Scope* scope) { scope_ = scope; }
323

324 325 326 327 328 329
  void InitializeStatements(const ScopedPtrList<Statement>& statements,
                            Zone* zone) {
    DCHECK_EQ(0, statements_.length());
    statements.CopyTo(&statements_, zone);
  }

330 331 332
 private:
  friend class AstNodeFactory;

333
  ZonePtrList<Statement> statements_;
334 335
  Scope* scope_;

336
  using IgnoreCompletionField = BreakableStatement::NextBitField<bool, 1>;
337
  using IsBreakableField = IgnoreCompletionField::Next<bool, 1>;
338 339

 protected:
340 341 342
  Block(Zone* zone, int capacity, bool ignore_completion_value,
        bool is_breakable)
      : BreakableStatement(kNoSourcePosition, kBlock),
343
        statements_(capacity, zone),
344
        scope_(nullptr) {
345
    bit_field_ |= IgnoreCompletionField::encode(ignore_completion_value) |
346
                  IsBreakableField::encode(is_breakable);
347 348
  }

349 350
  Block(bool ignore_completion_value, bool is_breakable)
      : Block(nullptr, 0, ignore_completion_value, is_breakable) {}
351 352
};

353
class Declaration : public AstNode {
354
 public:
355
  using List = base::ThreadedList<Declaration>;
356

357 358
  Variable* var() const { return var_; }
  void set_var(Variable* var) { var_ = var; }
359

360
 protected:
361
  Declaration(int pos, NodeType type) : AstNode(pos, type), next_(nullptr) {}
362 363

 private:
364
  Variable* var_;
365 366 367 368
  // Declarations list threaded through the declarations.
  Declaration** next() { return &next_; }
  Declaration* next_;
  friend List;
369
  friend base::ThreadedListTraits<Declaration>;
370 371
};

372 373 374
class VariableDeclaration : public Declaration {
 public:
  inline NestedVariableDeclaration* AsNested();
375

376 377 378
 private:
  friend class AstNodeFactory;

379
  using IsNestedField = Declaration::NextBitField<bool, 1>;
380 381

 protected:
382 383
  explicit VariableDeclaration(int pos, bool is_nested = false)
      : Declaration(pos, kVariableDeclaration) {
384 385 386
    bit_field_ = IsNestedField::update(bit_field_, is_nested);
  }

387 388
  template <class T, int size>
  using NextBitField = IsNestedField::Next<T, size>;
389 390
};

391 392 393 394 395 396 397 398 399 400
// For var declarations that appear in a block scope.
// Only distinguished from VariableDeclaration during Scope analysis,
// so it doesn't get its own NodeType.
class NestedVariableDeclaration final : public VariableDeclaration {
 public:
  Scope* scope() const { return scope_; }

 private:
  friend class AstNodeFactory;

401 402
  NestedVariableDeclaration(Scope* scope, int pos)
      : VariableDeclaration(pos, true), scope_(scope) {}
403 404 405 406 407 408 409 410 411 412

  // Nested scope from which the declaration originated.
  Scope* scope_;
};

inline NestedVariableDeclaration* VariableDeclaration::AsNested() {
  return IsNestedField::decode(bit_field_)
             ? static_cast<NestedVariableDeclaration*>(this)
             : nullptr;
}
413

414
class FunctionDeclaration final : public Declaration {
415 416
 public:
  FunctionLiteral* fun() const { return fun_; }
417

418 419 420
 private:
  friend class AstNodeFactory;

421 422
  FunctionDeclaration(FunctionLiteral* fun, int pos)
      : Declaration(pos, kFunctionDeclaration), fun_(fun) {}
423 424 425 426 427

  FunctionLiteral* fun_;
};


428
class IterationStatement : public BreakableStatement {
429 430
 public:
  Statement* body() const { return body_; }
431
  void set_body(Statement* s) { body_ = s; }
432 433

 protected:
434 435
  IterationStatement(int pos, NodeType type)
      : BreakableStatement(pos, type), body_(nullptr) {}
436
  void Initialize(Statement* body) { body_ = body; }
437

438
 private:
439 440 441 442
  Statement* body_;
};


443
class DoWhileStatement final : public IterationStatement {
444
 public:
445 446
  void Initialize(Expression* cond, Statement* body) {
    IterationStatement::Initialize(body);
447 448
    cond_ = cond;
  }
449

450 451
  Expression* cond() const { return cond_; }

452 453 454
 private:
  friend class AstNodeFactory;

455 456
  explicit DoWhileStatement(int pos)
      : IterationStatement(pos, kDoWhileStatement), cond_(nullptr) {}
457

458 459 460 461
  Expression* cond_;
};


462
class WhileStatement final : public IterationStatement {
463
 public:
464 465
  void Initialize(Expression* cond, Statement* body) {
    IterationStatement::Initialize(body);
466 467 468 469 470
    cond_ = cond;
  }

  Expression* cond() const { return cond_; }

471 472 473
 private:
  friend class AstNodeFactory;

474 475
  explicit WhileStatement(int pos)
      : IterationStatement(pos, kWhileStatement), cond_(nullptr) {}
476

477 478 479 480
  Expression* cond_;
};


481
class ForStatement final : public IterationStatement {
482
 public:
483
  void Initialize(Statement* init, Expression* cond, Statement* next,
484 485
                  Statement* body) {
    IterationStatement::Initialize(body);
486 487 488 489 490
    init_ = init;
    cond_ = cond;
    next_ = next;
  }

491 492 493
  Statement* init() const { return init_; }
  Expression* cond() const { return cond_; }
  Statement* next() const { return next_; }
494

495 496 497
 private:
  friend class AstNodeFactory;

498 499
  explicit ForStatement(int pos)
      : IterationStatement(pos, kForStatement),
500 501 502
        init_(nullptr),
        cond_(nullptr),
        next_(nullptr) {}
503

504 505 506 507 508
  Statement* init_;
  Expression* cond_;
  Statement* next_;
};

509
// Shared class for for-in and for-of statements.
510
class ForEachStatement : public IterationStatement {
511
 public:
512 513 514 515
  enum VisitMode {
    ENUMERATE,   // for (each in subject) body;
    ITERATE      // for (each of subject) body;
  };
516

517
  using IterationStatement::Initialize;
518

519 520 521 522
  static const char* VisitModeString(VisitMode mode) {
    return mode == ITERATE ? "for-of" : "for-in";
  }

523
  void Initialize(Expression* each, Expression* subject, Statement* body) {
524
    IterationStatement::Initialize(body);
525 526 527 528 529 530 531
    each_ = each;
    subject_ = subject;
  }

  Expression* each() const { return each_; }
  Expression* subject() const { return subject_; }

532
 protected:
533 534
  friend class AstNodeFactory;

535 536
  ForEachStatement(int pos, NodeType type)
      : IterationStatement(pos, type), each_(nullptr), subject_(nullptr) {}
537

538 539
  Expression* each_;
  Expression* subject_;
540
};
541

542 543 544 545
class ForInStatement final : public ForEachStatement {
 private:
  friend class AstNodeFactory;

546
  explicit ForInStatement(int pos) : ForEachStatement(pos, kForInStatement) {}
547
};
548

549
enum class IteratorType { kNormal, kAsync };
550
class ForOfStatement final : public ForEachStatement {
551
 public:
552
  IteratorType type() const { return type_; }
553

554 555 556
 private:
  friend class AstNodeFactory;

557 558
  ForOfStatement(int pos, IteratorType type)
      : ForEachStatement(pos, kForOfStatement), type_(type) {}
559

560
  IteratorType type_;
561 562
};

563
class ExpressionStatement final : public Statement {
564 565
 public:
  void set_expression(Expression* e) { expression_ = e; }
566
  Expression* expression() const { return expression_; }
567

568 569 570
 private:
  friend class AstNodeFactory;

571 572
  ExpressionStatement(Expression* expression, int pos)
      : Statement(pos, kExpressionStatement), expression_(expression) {}
573

574 575 576 577
  Expression* expression_;
};


578
class JumpStatement : public Statement {
579
 protected:
580
  JumpStatement(int pos, NodeType type) : Statement(pos, type) {}
581 582 583
};


584
class ContinueStatement final : public JumpStatement {
585
 public:
586
  IterationStatement* target() const { return target_; }
587

588 589 590
 private:
  friend class AstNodeFactory;

591 592
  ContinueStatement(IterationStatement* target, int pos)
      : JumpStatement(pos, kContinueStatement), target_(target) {}
593 594 595 596 597

  IterationStatement* target_;
};


598
class BreakStatement final : public JumpStatement {
599
 public:
600
  BreakableStatement* target() const { return target_; }
601

602 603 604
 private:
  friend class AstNodeFactory;

605 606
  BreakStatement(BreakableStatement* target, int pos)
      : JumpStatement(pos, kBreakStatement), target_(target) {}
607 608 609 610 611

  BreakableStatement* target_;
};


612
class ReturnStatement final : public JumpStatement {
613
 public:
614
  enum Type { kNormal, kAsyncReturn, kSyntheticAsyncReturn };
615
  Expression* expression() const { return expression_; }
616

617
  Type type() const { return TypeField::decode(bit_field_); }
618 619 620 621
  bool is_async_return() const { return type() != kNormal; }
  bool is_synthetic_async_return() const {
    return type() == kSyntheticAsyncReturn;
  }
622

623 624
  int end_position() const { return end_position_; }

625 626 627
 private:
  friend class AstNodeFactory;

628 629 630 631
  ReturnStatement(Expression* expression, Type type, int pos, int end_position)
      : JumpStatement(pos, kReturnStatement),
        expression_(expression),
        end_position_(end_position) {
632 633
    bit_field_ |= TypeField::encode(type);
  }
634 635

  Expression* expression_;
636
  int end_position_;
637

638
  using TypeField = JumpStatement::NextBitField<Type, 2>;
639 640 641
};


642
class WithStatement final : public Statement {
643
 public:
644
  Scope* scope() { return scope_; }
645
  Expression* expression() const { return expression_; }
646
  Statement* statement() const { return statement_; }
647
  void set_statement(Statement* s) { statement_ = s; }
648

649 650 651
 private:
  friend class AstNodeFactory;

652 653 654
  WithStatement(Scope* scope, Expression* expression, Statement* statement,
                int pos)
      : Statement(pos, kWithStatement),
655
        scope_(scope),
656
        expression_(expression),
657
        statement_(statement) {}
658

659
  Scope* scope_;
660
  Expression* expression_;
661
  Statement* statement_;
662 663
};

664
class CaseClause final : public ZoneObject {
665
 public:
666
  bool is_default() const { return label_ == nullptr; }
667
  Expression* label() const {
668
    DCHECK(!is_default());
669 670
    return label_;
  }
671
  ZonePtrList<Statement>* statements() { return &statements_; }
672 673

 private:
674 675
  friend class AstNodeFactory;

676 677
  CaseClause(Zone* zone, Expression* label,
             const ScopedPtrList<Statement>& statements);
678

679
  Expression* label_;
680
  ZonePtrList<Statement> statements_;
681 682 683
};


684
class SwitchStatement final : public BreakableStatement {
685
 public:
686
  Expression* tag() const { return tag_; }
687 688
  void set_tag(Expression* t) { tag_ = t; }

689
  ZonePtrList<CaseClause>* cases() { return &cases_; }
690

691 692 693
 private:
  friend class AstNodeFactory;

694 695
  SwitchStatement(Zone* zone, Expression* tag, int pos)
      : BreakableStatement(pos, kSwitchStatement), tag_(tag), cases_(4, zone) {}
696 697

  Expression* tag_;
698
  ZonePtrList<CaseClause> cases_;
699 700 701 702 703 704 705 706
};


// If-statements always have non-null references to their then- and
// else-parts. When parsing if-statements with no explicit else-part,
// the parser implicitly creates an empty statement. Use the
// HasThenStatement() and HasElseStatement() functions to check if a
// given if-statement has a then- or an else-part containing code.
707
class IfStatement final : public Statement {
708
 public:
709 710
  bool HasThenStatement() const { return !then_statement_->IsEmptyStatement(); }
  bool HasElseStatement() const { return !else_statement_->IsEmptyStatement(); }
711 712 713 714 715

  Expression* condition() const { return condition_; }
  Statement* then_statement() const { return then_statement_; }
  Statement* else_statement() const { return else_statement_; }

716 717 718
  void set_then_statement(Statement* s) { then_statement_ = s; }
  void set_else_statement(Statement* s) { else_statement_ = s; }

719 720 721
 private:
  friend class AstNodeFactory;

722
  IfStatement(Expression* condition, Statement* then_statement,
723
              Statement* else_statement, int pos)
724
      : Statement(pos, kIfStatement),
725
        condition_(condition),
726
        then_statement_(then_statement),
727
        else_statement_(else_statement) {}
728

729 730 731 732 733 734
  Expression* condition_;
  Statement* then_statement_;
  Statement* else_statement_;
};


735
class TryStatement : public Statement {
736 737
 public:
  Block* try_block() const { return try_block_; }
738
  void set_try_block(Block* b) { try_block_ = b; }
739 740

 protected:
741
  TryStatement(Block* try_block, int pos, NodeType type)
742
      : Statement(pos, type), try_block_(try_block) {}
743

744
 private:
745
  Block* try_block_;
746 747 748
};


749
class TryCatchStatement final : public TryStatement {
750
 public:
751 752
  Scope* scope() { return scope_; }
  Block* catch_block() const { return catch_block_; }
753
  void set_catch_block(Block* b) { catch_block_ = b; }
754

755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793
  // Prediction of whether exceptions thrown into the handler for this try block
  // will be caught.
  //
  // BytecodeGenerator tracks the state of catch prediction, which can change
  // with each TryCatchStatement encountered. The tracked catch prediction is
  // later compiled into the code's handler table. The runtime uses this
  // information to implement a feature that notifies the debugger when an
  // uncaught exception is thrown, _before_ the exception propagates to the top.
  //
  // If this try/catch statement is meant to rethrow (HandlerTable::UNCAUGHT),
  // the catch prediction value is set to the same value as the surrounding
  // catch prediction.
  //
  // Since it's generally undecidable whether an exception will be caught, our
  // prediction is only an approximation.
  // ---------------------------------------------------------------------------
  inline HandlerTable::CatchPrediction GetCatchPrediction(
      HandlerTable::CatchPrediction outer_catch_prediction) const {
    if (catch_prediction_ == HandlerTable::UNCAUGHT) {
      return outer_catch_prediction;
    }
    return catch_prediction_;
  }

  // Indicates whether or not code should be generated to clear the pending
  // exception. The pending exception is cleared for cases where the exception
  // is not guaranteed to be rethrown, indicated by the value
  // HandlerTable::UNCAUGHT. If both the current and surrounding catch handler's
  // are predicted uncaught, the exception is not cleared.
  //
  // If this handler is not going to simply rethrow the exception, this method
  // indicates that the isolate's pending exception message should be cleared
  // before executing the catch_block.
  // In the normal use case, this flag is always on because the message object
  // is not needed anymore when entering the catch block and should not be
  // kept alive.
  // The use case where the flag is off is when the catch block is guaranteed
  // to rethrow the caught exception (using %ReThrow), which reuses the
  // pending message instead of generating a new one.
794
  // (When the catch block doesn't rethrow but is guaranteed to perform an
795 796
  // ordinary throw, not clearing the old message is safe but not very
  // useful.)
797 798 799 800
  //
  // For scripts in repl mode there is exactly one catch block with
  // UNCAUGHT_ASYNC_AWAIT prediction. This catch block needs to preserve
  // the exception so it can be re-used later by the inspector.
801 802
  inline bool ShouldClearPendingException(
      HandlerTable::CatchPrediction outer_catch_prediction) const {
803 804 805 806 807
    if (catch_prediction_ == HandlerTable::UNCAUGHT_ASYNC_AWAIT) {
      DCHECK_EQ(outer_catch_prediction, HandlerTable::UNCAUGHT);
      return false;
    }

808 809
    return catch_prediction_ != HandlerTable::UNCAUGHT ||
           outer_catch_prediction != HandlerTable::UNCAUGHT;
810
  }
811

812 813 814 815
  bool is_try_catch_for_async() {
    return catch_prediction_ == HandlerTable::ASYNC_AWAIT;
  }

816 817 818
 private:
  friend class AstNodeFactory;

819
  TryCatchStatement(Block* try_block, Scope* scope, Block* catch_block,
820
                    HandlerTable::CatchPrediction catch_prediction, int pos)
821
      : TryStatement(try_block, pos, kTryCatchStatement),
822
        scope_(scope),
823
        catch_block_(catch_block),
824
        catch_prediction_(catch_prediction) {}
825

826
  Scope* scope_;
827
  Block* catch_block_;
828
  HandlerTable::CatchPrediction catch_prediction_;
829 830 831
};


832
class TryFinallyStatement final : public TryStatement {
833 834
 public:
  Block* finally_block() const { return finally_block_; }
835
  void set_finally_block(Block* b) { finally_block_ = b; }
836

837 838 839
 private:
  friend class AstNodeFactory;

840
  TryFinallyStatement(Block* try_block, Block* finally_block, int pos)
841
      : TryStatement(try_block, pos, kTryFinallyStatement),
842
        finally_block_(finally_block) {}
843 844 845 846 847

  Block* finally_block_;
};


848
class DebuggerStatement final : public Statement {
849 850 851
 private:
  friend class AstNodeFactory;

852
  explicit DebuggerStatement(int pos) : Statement(pos, kDebuggerStatement) {}
853 854 855
};


856
class EmptyStatement final : public Statement {
857 858
 private:
  friend class AstNodeFactory;
859
  EmptyStatement() : Statement(kNoSourcePosition, kEmptyStatement) {}
860 861 862
};


863 864 865 866 867 868 869 870
// Delegates to another statement, which may be overwritten.
// This was introduced to implement ES2015 Annex B3.3 for conditionally making
// sloppy-mode block-scoped functions have a var binding, which is changed
// from one statement to another during parsing.
class SloppyBlockFunctionStatement final : public Statement {
 public:
  Statement* statement() const { return statement_; }
  void set_statement(Statement* statement) { statement_ = statement; }
871 872 873 874 875
  Scope* scope() const { return var_->scope(); }
  Variable* var() const { return var_; }
  Token::Value init() const { return TokenField::decode(bit_field_); }
  const AstRawString* name() const { return var_->raw_name(); }
  SloppyBlockFunctionStatement** next() { return &next_; }
876 877

 private:
878 879
  friend class AstNodeFactory;

880
  using TokenField = Statement::NextBitField<Token::Value, 8>;
881 882 883 884 885 886 887 888 889

  SloppyBlockFunctionStatement(int pos, Variable* var, Token::Value init,
                               Statement* statement)
      : Statement(pos, kSloppyBlockFunctionStatement),
        var_(var),
        statement_(statement),
        next_(nullptr) {
    bit_field_ = TokenField::update(bit_field_, init);
  }
890

891
  Variable* var_;
892
  Statement* statement_;
893
  SloppyBlockFunctionStatement* next_;
894 895 896
};


897
class Literal final : public Expression {
898
 public:
899 900 901 902 903 904 905 906 907 908 909 910 911 912
  enum Type {
    kSmi,
    kHeapNumber,
    kBigInt,
    kString,
    kSymbol,
    kBoolean,
    kUndefined,
    kNull,
    kTheHole,
  };

  Type type() const { return TypeField::decode(bit_field_); }

913
  // Returns true if literal represents a property name (i.e. cannot be parsed
914
  // as array indices).
915
  bool IsPropertyName() const;
916 917 918 919 920 921 922 923

  // Returns true if literal represents an array index.
  // Note, that in general the following statement is not true:
  //   key->IsPropertyName() != key->AsArrayIndex(...)
  // but for non-computed LiteralProperty properties the following is true:
  //   property->key()->IsPropertyName() != property->key()->AsArrayIndex(...)
  bool AsArrayIndex(uint32_t* index) const;

924
  const AstRawString* AsRawPropertyName() {
925
    DCHECK(IsPropertyName());
926
    return string_;
927 928
  }

929
  Smi AsSmiLiteral() const {
930 931
    DCHECK_EQ(kSmi, type());
    return Smi::FromInt(smi_);
932 933
  }

934
  // Returns true if literal represents a Number.
935
  bool IsNumber() const { return type() == kHeapNumber || type() == kSmi; }
936 937
  double AsNumber() const {
    DCHECK(IsNumber());
938 939 940 941 942 943 944 945
    switch (type()) {
      case kSmi:
        return smi_;
      case kHeapNumber:
        return number_;
      default:
        UNREACHABLE();
    }
946 947
  }

948
  AstBigInt AsBigInt() const {
949
    DCHECK_EQ(type(), kBigInt);
950 951 952 953
    return bigint_;
  }

  bool IsString() const { return type() == kString; }
954
  const AstRawString* AsRawString() {
955
    DCHECK_EQ(type(), kString);
956 957 958 959
    return string_;
  }

  AstSymbol AsSymbol() {
960
    DCHECK_EQ(type(), kSymbol);
961
    return symbol_;
962 963
  }

964 965
  V8_EXPORT_PRIVATE bool ToBooleanIsTrue() const;
  bool ToBooleanIsFalse() const { return !ToBooleanIsTrue(); }
966 967

  bool ToUint32(uint32_t* value) const;
968

969 970
  // Returns an appropriate Object representing this Literal, allocating
  // a heap object if needed.
971 972
  template <typename LocalIsolate>
  Handle<Object> BuildValue(LocalIsolate* isolate) const;
973

974 975
  // Support for using Literal as a HashMap key. NOTE: Currently, this works
  // only for string and number literals!
976 977
  uint32_t Hash();
  static bool Match(void* literal1, void* literal2);
978

979 980 981
 private:
  friend class AstNodeFactory;

982
  using TypeField = Expression::NextBitField<Type, 4>;
983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006

  Literal(int smi, int position) : Expression(position, kLiteral), smi_(smi) {
    bit_field_ = TypeField::update(bit_field_, kSmi);
  }

  Literal(double number, int position)
      : Expression(position, kLiteral), number_(number) {
    bit_field_ = TypeField::update(bit_field_, kHeapNumber);
  }

  Literal(AstBigInt bigint, int position)
      : Expression(position, kLiteral), bigint_(bigint) {
    bit_field_ = TypeField::update(bit_field_, kBigInt);
  }

  Literal(const AstRawString* string, int position)
      : Expression(position, kLiteral), string_(string) {
    bit_field_ = TypeField::update(bit_field_, kString);
  }

  Literal(AstSymbol symbol, int position)
      : Expression(position, kLiteral), symbol_(symbol) {
    bit_field_ = TypeField::update(bit_field_, kSymbol);
  }
1007

1008 1009 1010 1011 1012
  Literal(bool boolean, int position)
      : Expression(position, kLiteral), boolean_(boolean) {
    bit_field_ = TypeField::update(bit_field_, kBoolean);
  }

1013
  Literal(Type type, int position) : Expression(position, kLiteral) {
1014
    DCHECK(type == kNull || type == kUndefined || type == kTheHole);
1015 1016 1017 1018 1019 1020 1021 1022 1023
    bit_field_ = TypeField::update(bit_field_, type);
  }

  union {
    const AstRawString* string_;
    int smi_;
    double number_;
    AstSymbol symbol_;
    AstBigInt bigint_;
1024
    bool boolean_;
1025
  };
1026 1027
};

1028
// Base class for literals that need space in the type feedback vector.
1029
class MaterializedLiteral : public Expression {
1030
 public:
1031 1032 1033 1034
  // A Materializedliteral is simple if the values consist of only
  // constants and simple object and array literals.
  bool IsSimple() const;

1035
 protected:
1036
  MaterializedLiteral(int pos, NodeType type) : Expression(pos, type) {}
1037

1038
  friend class CompileTimeValue;
1039 1040
  friend class ArrayLiteral;
  friend class ObjectLiteral;
1041

1042 1043
  // Populate the depth field and any flags the literal has, returns the depth.
  int InitDepthAndFlags();
1044

1045
  bool NeedsInitialAllocationSite();
1046

1047
  // Populate the constant properties/elements fixed array.
1048 1049
  template <typename LocalIsolate>
  void BuildConstants(LocalIsolate* isolate);
1050 1051

  // If the expression is a literal, return the literal value;
1052 1053
  // if the expression is a materialized literal and is_simple
  // then return an Array or Object Boilerplate Description
1054 1055
  // Otherwise, return undefined literal as the placeholder
  // in the object literal boilerplate.
1056 1057 1058
  template <typename LocalIsolate>
  Handle<Object> GetBoilerplateValue(Expression* expression,
                                     LocalIsolate* isolate);
1059 1060 1061 1062 1063
};

// Node for capturing a regexp literal.
class RegExpLiteral final : public MaterializedLiteral {
 public:
1064
  Handle<String> pattern() const { return pattern_->string(); }
1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113
  const AstRawString* raw_pattern() const { return pattern_; }
  int flags() const { return flags_; }

 private:
  friend class AstNodeFactory;

  RegExpLiteral(const AstRawString* pattern, int flags, int pos)
      : MaterializedLiteral(pos, kRegExpLiteral),
        flags_(flags),
        pattern_(pattern) {}

  int const flags_;
  const AstRawString* const pattern_;
};

// Base class for Array and Object literals, providing common code for handling
// nested subliterals.
class AggregateLiteral : public MaterializedLiteral {
 public:
  enum Flags {
    kNoFlags = 0,
    kIsShallow = 1,
    kDisableMementos = 1 << 1,
    kNeedsInitialAllocationSite = 1 << 2,
  };

  bool is_initialized() const { return 0 < depth_; }
  int depth() const {
    DCHECK(is_initialized());
    return depth_;
  }

  bool is_shallow() const { return depth() == 1; }
  bool needs_initial_allocation_site() const {
    return NeedsInitialAllocationSiteField::decode(bit_field_);
  }

  int ComputeFlags(bool disable_mementos = false) const {
    int flags = kNoFlags;
    if (is_shallow()) flags |= kIsShallow;
    if (disable_mementos) flags |= kDisableMementos;
    if (needs_initial_allocation_site()) flags |= kNeedsInitialAllocationSite;
    return flags;
  }

  // An AggregateLiteral is simple if the values consist of only
  // constants and simple object and array literals.
  bool is_simple() const { return IsSimpleField::decode(bit_field_); }

1114 1115 1116 1117
  ElementsKind boilerplate_descriptor_kind() const {
    return BoilerplateDescriptorKindField::decode(bit_field_);
  }

1118 1119
 private:
  int depth_ : 31;
1120
  using NeedsInitialAllocationSiteField =
1121 1122
      MaterializedLiteral::NextBitField<bool, 1>;
  using IsSimpleField = NeedsInitialAllocationSiteField::Next<bool, 1>;
1123 1124
  using BoilerplateDescriptorKindField =
      IsSimpleField::Next<ElementsKind, kFastElementsKindBits>;
1125 1126 1127 1128 1129

 protected:
  friend class AstNodeFactory;
  AggregateLiteral(int pos, NodeType type)
      : MaterializedLiteral(pos, type), depth_(0) {
1130 1131 1132 1133
    bit_field_ |=
        NeedsInitialAllocationSiteField::encode(false) |
        IsSimpleField::encode(false) |
        BoilerplateDescriptorKindField::encode(FIRST_FAST_ELEMENTS_KIND);
1134 1135 1136 1137 1138 1139
  }

  void set_is_simple(bool is_simple) {
    bit_field_ = IsSimpleField::update(bit_field_, is_simple);
  }

1140 1141 1142 1143 1144
  void set_boilerplate_descriptor_kind(ElementsKind kind) {
    DCHECK(IsFastElementsKind(kind));
    bit_field_ = BoilerplateDescriptorKindField::update(bit_field_, kind);
  }

1145 1146 1147 1148 1149 1150 1151 1152
  void set_depth(int depth) {
    DCHECK(!is_initialized());
    depth_ = depth;
  }

  void set_needs_initial_allocation_site(bool required) {
    bit_field_ = NeedsInitialAllocationSiteField::update(bit_field_, required);
  }
1153

1154
  template <class T, int size>
1155
  using NextBitField = BoilerplateDescriptorKindField::Next<T, size>;
1156 1157
};

1158 1159 1160
// Common supertype for ObjectLiteralProperty and ClassLiteralProperty
class LiteralProperty : public ZoneObject {
 public:
1161
  Expression* key() const { return key_and_is_computed_name_.GetPointer(); }
1162 1163
  Expression* value() const { return value_; }

1164 1165 1166
  bool is_computed_name() const {
    return key_and_is_computed_name_.GetPayload();
  }
1167 1168 1169 1170
  bool NeedsSetFunctionName() const;

 protected:
  LiteralProperty(Expression* key, Expression* value, bool is_computed_name)
1171
      : key_and_is_computed_name_(key, is_computed_name), value_(value) {}
1172

1173
  PointerWithPayload<Expression, bool, 1> key_and_is_computed_name_;
1174 1175
  Expression* value_;
};
1176

1177 1178 1179
// Property is used for passing information
// about an object literal's properties from the parser
// to the code generator.
1180
class ObjectLiteralProperty final : public LiteralProperty {
1181
 public:
1182
  enum Kind : uint8_t {
1183 1184 1185
    CONSTANT,              // Property with constant value (compile time).
    COMPUTED,              // Property with computed value (execution time).
    MATERIALIZED_LITERAL,  // Property value is a materialized literal.
1186
    GETTER,
1187 1188 1189
    SETTER,     // Property is an accessor function.
    PROTOTYPE,  // Property is __proto__.
    SPREAD
1190 1191
  };

1192
  Kind kind() const { return kind_; }
1193

1194
  bool IsCompileTimeValue() const;
1195 1196

  void set_emit_store(bool emit_store);
1197
  bool emit_store() const;
1198

1199 1200 1201 1202 1203
  bool IsNullPrototype() const {
    return IsPrototype() && value()->IsNullLiteral();
  }
  bool IsPrototype() const { return kind() == PROTOTYPE; }

1204
 private:
1205
  friend class AstNodeFactory;
1206

1207
  ObjectLiteralProperty(Expression* key, Expression* value, Kind kind,
arv's avatar
arv committed
1208
                        bool is_computed_name);
1209 1210
  ObjectLiteralProperty(AstValueFactory* ast_value_factory, Expression* key,
                        Expression* value, bool is_computed_name);
1211 1212 1213 1214 1215

  Kind kind_;
  bool emit_store_;
};

1216 1217
// An object literal has a boilerplate object that is used
// for minimizing the work when constructing it at runtime.
1218
class ObjectLiteral final : public AggregateLiteral {
1219
 public:
1220
  using Property = ObjectLiteralProperty;
1221

1222 1223
  Handle<ObjectBoilerplateDescription> boilerplate_description() const {
    DCHECK(!boilerplate_description_.is_null());
1224
    return boilerplate_description_;
1225
  }
1226
  int properties_count() const { return boilerplate_properties_; }
1227
  const ZonePtrList<Property>* properties() const { return &properties_; }
1228
  bool has_elements() const { return HasElementsField::decode(bit_field_); }
1229 1230 1231
  bool has_rest_property() const {
    return HasRestPropertyField::decode(bit_field_);
  }
1232
  bool fast_elements() const { return FastElementsField::decode(bit_field_); }
1233 1234 1235
  bool has_null_prototype() const {
    return HasNullPrototypeField::decode(bit_field_);
  }
1236

1237 1238 1239 1240 1241 1242 1243 1244 1245 1246
  bool is_empty() const {
    DCHECK(is_initialized());
    return !has_elements() && properties_count() == 0 &&
           properties()->length() == 0;
  }

  bool IsEmptyObjectLiteral() const {
    return is_empty() && !has_null_prototype();
  }

1247 1248
  // Populate the depth field and flags, returns the depth.
  int InitDepthAndFlags();
1249

1250
  // Get the boilerplate description, populating it if necessary.
1251 1252 1253
  template <typename LocalIsolate>
  Handle<ObjectBoilerplateDescription> GetOrBuildBoilerplateDescription(
      LocalIsolate* isolate) {
1254 1255
    if (boilerplate_description_.is_null()) {
      BuildBoilerplateDescription(isolate);
1256
    }
1257
    return boilerplate_description();
1258 1259
  }

1260
  // Populate the boilerplate description.
1261 1262
  template <typename LocalIsolate>
  void BuildBoilerplateDescription(LocalIsolate* isolate);
1263

1264 1265 1266
  // Mark all computed expressions that are bound to a key that
  // is shadowed by a later occurrence of the same key. For the
  // marked expressions, no store code is emitted.
1267
  void CalculateEmitStore(Zone* zone);
1268

1269
  // Determines whether the {CreateShallowObjectLiteratal} builtin can be used.
1270 1271
  bool IsFastCloningSupported() const;

1272
  // Assemble bitfield of flags for the CreateObjectLiteral helper.
1273
  int ComputeFlags(bool disable_mementos = false) const {
1274 1275
    int flags = AggregateLiteral::ComputeFlags(disable_mementos);
    if (fast_elements()) flags |= kFastElements;
1276 1277 1278 1279 1280
    if (has_null_prototype()) flags |= kHasNullPrototype;
    return flags;
  }

  int EncodeLiteralType() {
1281 1282
    int flags = kNoFlags;
    if (fast_elements()) flags |= kFastElements;
1283
    if (has_null_prototype()) flags |= kHasNullPrototype;
1284 1285 1286
    return flags;
  }

1287
  enum Flags {
1288 1289
    kFastElements = 1 << 3,
    kHasNullPrototype = 1 << 4,
1290
  };
1291 1292 1293
  STATIC_ASSERT(
      static_cast<int>(AggregateLiteral::kNeedsInitialAllocationSite) <
      static_cast<int>(kFastElements));
1294

1295 1296 1297
 private:
  friend class AstNodeFactory;

1298
  ObjectLiteral(Zone* zone, const ScopedPtrList<Property>& properties,
1299
                uint32_t boilerplate_properties, int pos,
1300
                bool has_rest_property)
1301
      : AggregateLiteral(pos, kObjectLiteral),
1302
        boilerplate_properties_(boilerplate_properties),
1303
        properties_(0, nullptr) {
1304
    bit_field_ |= HasElementsField::encode(false) |
1305
                  HasRestPropertyField::encode(has_rest_property) |
1306
                  FastElementsField::encode(false) |
1307
                  HasNullPrototypeField::encode(false);
1308
    properties.CopyTo(&properties_, zone);
1309
  }
1310

1311 1312 1313 1314 1315
  void InitFlagsForPendingNullPrototype(int i);

  void set_has_elements(bool has_elements) {
    bit_field_ = HasElementsField::update(bit_field_, has_elements);
  }
1316 1317 1318
  void set_fast_elements(bool fast_elements) {
    bit_field_ = FastElementsField::update(bit_field_, fast_elements);
  }
1319 1320 1321
  void set_has_null_protoype(bool has_null_prototype) {
    bit_field_ = HasNullPrototypeField::update(bit_field_, has_null_prototype);
  }
1322
  uint32_t boilerplate_properties_;
1323
  Handle<ObjectBoilerplateDescription> boilerplate_description_;
1324
  ZoneList<Property*> properties_;
1325

1326 1327 1328 1329
  using HasElementsField = AggregateLiteral::NextBitField<bool, 1>;
  using HasRestPropertyField = HasElementsField::Next<bool, 1>;
  using FastElementsField = HasRestPropertyField::Next<bool, 1>;
  using HasNullPrototypeField = FastElementsField::Next<bool, 1>;
1330 1331 1332
};

// An array literal has a literals object that is used
1333
// for minimizing the work when constructing it at runtime.
1334
class ArrayLiteral final : public AggregateLiteral {
1335
 public:
1336
  Handle<ArrayBoilerplateDescription> boilerplate_description() const {
1337
    return boilerplate_description_;
1338
  }
1339

1340
  const ZonePtrList<Expression>* values() const { return &values_; }
1341

1342 1343
  int first_spread_index() const { return first_spread_index_; }

1344 1345
  // Populate the depth field and flags, returns the depth.
  int InitDepthAndFlags();
1346

1347
  // Get the boilerplate description, populating it if necessary.
1348 1349 1350
  template <typename LocalIsolate>
  Handle<ArrayBoilerplateDescription> GetOrBuildBoilerplateDescription(
      LocalIsolate* isolate) {
1351 1352
    if (boilerplate_description_.is_null()) {
      BuildBoilerplateDescription(isolate);
1353
    }
1354
    return boilerplate_description_;
1355 1356
  }

1357
  // Populate the boilerplate description.
1358 1359
  template <typename LocalIsolate>
  void BuildBoilerplateDescription(LocalIsolate* isolate);
1360

1361
  // Determines whether the {CreateShallowArrayLiteral} builtin can be used.
1362 1363
  bool IsFastCloningSupported() const;

1364
  // Assemble bitfield of flags for the CreateArrayLiteral helper.
1365
  int ComputeFlags(bool disable_mementos = false) const {
1366
    return AggregateLiteral::ComputeFlags(disable_mementos);
1367 1368
  }

1369 1370 1371
 private:
  friend class AstNodeFactory;

1372 1373
  ArrayLiteral(Zone* zone, const ScopedPtrList<Expression>& values,
               int first_spread_index, int pos)
1374
      : AggregateLiteral(pos, kArrayLiteral),
1375
        first_spread_index_(first_spread_index),
1376
        values_(0, nullptr) {
1377
    values.CopyTo(&values_, zone);
1378
  }
1379

1380
  int first_spread_index_;
1381
  Handle<ArrayBoilerplateDescription> boilerplate_description_;
1382
  ZonePtrList<Expression> values_;
1383 1384
};

1385
enum class HoleCheckMode { kRequired, kElided };
1386

1387 1388 1389 1390 1391 1392
class ThisExpression final : public Expression {
 private:
  friend class AstNodeFactory;
  ThisExpression() : Expression(kNoSourcePosition, kThisExpression) {}
};

1393
class VariableProxy final : public Expression {
1394
 public:
1395
  bool IsValidReferenceExpression() const { return !is_new_target(); }
1396

1397
  Handle<String> name() const { return raw_name()->string(); }
1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410
  const AstRawString* raw_name() const {
    return is_resolved() ? var_->raw_name() : raw_name_;
  }

  Variable* var() const {
    DCHECK(is_resolved());
    return var_;
  }
  void set_var(Variable* v) {
    DCHECK(!is_resolved());
    DCHECK_NOT_NULL(v);
    var_ = v;
  }
1411

1412 1413 1414 1415
  Scanner::Location location() {
    return Scanner::Location(position(), position() + raw_name()->length());
  }

1416 1417 1418
  bool is_assigned() const { return IsAssignedField::decode(bit_field_); }
  void set_is_assigned() {
    bit_field_ = IsAssignedField::update(bit_field_, true);
1419
    if (is_resolved()) {
1420
      var()->SetMaybeAssigned();
1421
    }
1422
  }
1423 1424 1425
  void clear_is_assigned() {
    bit_field_ = IsAssignedField::update(bit_field_, false);
  }
1426

1427 1428 1429 1430
  bool is_resolved() const { return IsResolvedField::decode(bit_field_); }
  void set_is_resolved() {
    bit_field_ = IsResolvedField::update(bit_field_, true);
  }
1431

1432 1433 1434 1435 1436
  bool is_new_target() const { return IsNewTargetField::decode(bit_field_); }
  void set_is_new_target() {
    bit_field_ = IsNewTargetField::update(bit_field_, true);
  }

1437
  HoleCheckMode hole_check_mode() const {
1438 1439 1440 1441 1442
    HoleCheckMode mode = HoleCheckModeField::decode(bit_field_);
    DCHECK_IMPLIES(mode == HoleCheckMode::kRequired,
                   var()->binding_needs_init() ||
                       var()->local_if_not_shadowed()->binding_needs_init());
    return mode;
1443 1444
  }
  void set_needs_hole_check() {
1445 1446
    bit_field_ =
        HoleCheckModeField::update(bit_field_, HoleCheckMode::kRequired);
1447 1448
  }

1449
  bool IsPrivateName() const { return raw_name()->IsPrivateName(); }
1450

1451
  // Bind this proxy to the variable var.
1452 1453
  void BindTo(Variable* var);

1454
  V8_INLINE VariableProxy* next_unresolved() { return next_unresolved_; }
1455 1456 1457 1458 1459 1460 1461
  V8_INLINE bool is_removed_from_unresolved() const {
    return IsRemovedFromUnresolvedField::decode(bit_field_);
  }

  void mark_removed_from_unresolved() {
    bit_field_ = IsRemovedFromUnresolvedField::update(bit_field_, true);
  }
1462

1463
  // Provides filtered access to the unresolved variable proxy threaded list.
1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476
  struct UnresolvedNext {
    static VariableProxy** filter(VariableProxy** t) {
      VariableProxy** n = t;
      // Skip over possibly removed values.
      while (*n != nullptr && (*n)->is_removed_from_unresolved()) {
        n = (*n)->next();
      }
      return n;
    }

    static VariableProxy** start(VariableProxy** head) { return filter(head); }

    static VariableProxy** next(VariableProxy* t) { return filter(t->next()); }
1477 1478
  };

1479 1480 1481
 private:
  friend class AstNodeFactory;

1482
  VariableProxy(Variable* var, int start_position);
1483

1484
  VariableProxy(const AstRawString* name, VariableKind variable_kind,
1485 1486 1487
                int start_position)
      : Expression(start_position, kVariableProxy),
        raw_name_(name),
1488
        next_unresolved_(nullptr) {
1489 1490
    DCHECK_NE(THIS_VARIABLE, variable_kind);
    bit_field_ |= IsAssignedField::encode(false) |
1491
                  IsResolvedField::encode(false) |
1492
                  IsRemovedFromUnresolvedField::encode(false) |
1493
                  HoleCheckModeField::encode(HoleCheckMode::kElided);
1494 1495
  }

1496
  explicit VariableProxy(const VariableProxy* copy_from);
1497

1498 1499 1500 1501 1502
  using IsAssignedField = Expression::NextBitField<bool, 1>;
  using IsResolvedField = IsAssignedField::Next<bool, 1>;
  using IsRemovedFromUnresolvedField = IsResolvedField::Next<bool, 1>;
  using IsNewTargetField = IsRemovedFromUnresolvedField::Next<bool, 1>;
  using HoleCheckModeField = IsNewTargetField::Next<HoleCheckMode, 1>;
1503

1504 1505 1506 1507
  union {
    const AstRawString* raw_name_;  // if !is_resolved_
    Variable* var_;                 // if is_resolved_
  };
1508 1509

  V8_INLINE VariableProxy** next() { return &next_unresolved_; }
1510
  VariableProxy* next_unresolved_;
1511

1512
  friend base::ThreadedListTraits<VariableProxy>;
1513
};
1514

1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528
// Wraps an optional chain to provide a wrapper for jump labels.
class OptionalChain final : public Expression {
 public:
  Expression* expression() const { return expression_; }

 private:
  friend class AstNodeFactory;

  explicit OptionalChain(Expression* expression)
      : Expression(0, kOptionalChain), expression_(expression) {}

  Expression* expression_;
};

1529 1530 1531 1532
// Assignments to a property will use one of several types of property access.
// Otherwise, the assignment is to a non-property (a global, a local slot, a
// parameter slot, or a destructuring pattern).
enum AssignType {
1533 1534 1535 1536 1537 1538 1539 1540 1541
  NON_PROPERTY,              // destructuring
  NAMED_PROPERTY,            // obj.key
  KEYED_PROPERTY,            // obj[key]
  NAMED_SUPER_PROPERTY,      // super.key
  KEYED_SUPER_PROPERTY,      // super[key]
  PRIVATE_METHOD,            // obj.#key: #key is a private method
  PRIVATE_GETTER_ONLY,       // obj.#key: #key only has a getter defined
  PRIVATE_SETTER_ONLY,       // obj.#key: #key only has a setter defined
  PRIVATE_GETTER_AND_SETTER  // obj.#key: #key has both accessors defined
1542 1543
};

1544
class Property final : public Expression {
1545
 public:
1546 1547 1548 1549
  bool is_optional_chain_link() const {
    return IsOptionalChainLinkField::decode(bit_field_);
  }

1550
  bool IsValidReferenceExpression() const { return true; }
1551 1552 1553 1554

  Expression* obj() const { return obj_; }
  Expression* key() const { return key_; }

1555
  bool IsSuperAccess() { return obj()->IsSuperPropertyReference(); }
1556
  bool IsPrivateReference() const { return key()->IsPrivateName(); }
1557

1558
  // Returns the properties assign type.
1559 1560
  static AssignType GetAssignType(Property* property) {
    if (property == nullptr) return NON_PROPERTY;
1561 1562 1563 1564 1565
    if (property->IsPrivateReference()) {
      DCHECK(!property->IsSuperAccess());
      VariableProxy* proxy = property->key()->AsVariableProxy();
      DCHECK_NOT_NULL(proxy);
      Variable* var = proxy->var();
1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580

      switch (var->mode()) {
        case VariableMode::kPrivateMethod:
          return PRIVATE_METHOD;
        case VariableMode::kConst:
          return KEYED_PROPERTY;  // Use KEYED_PROPERTY for private fields.
        case VariableMode::kPrivateGetterOnly:
          return PRIVATE_GETTER_ONLY;
        case VariableMode::kPrivateSetterOnly:
          return PRIVATE_SETTER_ONLY;
        case VariableMode::kPrivateGetterAndSetter:
          return PRIVATE_GETTER_AND_SETTER;
        default:
          UNREACHABLE();
      }
1581
    }
1582
    bool super_access = property->IsSuperAccess();
1583
    return (property->key()->IsPropertyName())
1584 1585 1586 1587
               ? (super_access ? NAMED_SUPER_PROPERTY : NAMED_PROPERTY)
               : (super_access ? KEYED_SUPER_PROPERTY : KEYED_PROPERTY);
  }

1588 1589 1590
 private:
  friend class AstNodeFactory;

1591
  Property(Expression* obj, Expression* key, int pos, bool optional_chain)
1592
      : Expression(pos, kProperty), obj_(obj), key_(key) {
1593
    bit_field_ |= IsOptionalChainLinkField::encode(optional_chain);
1594
  }
1595

1596 1597
  using IsOptionalChainLinkField = Expression::NextBitField<bool, 1>;

1598 1599
  Expression* obj_;
  Expression* key_;
1600 1601
};

1602
class Call final : public Expression {
1603 1604
 public:
  Expression* expression() const { return expression_; }
1605
  const ZonePtrList<Expression>* arguments() const { return &arguments_; }
1606

1607 1608 1609 1610
  bool is_possibly_eval() const {
    return IsPossiblyEvalField::decode(bit_field_);
  }

1611 1612 1613 1614
  bool is_tagged_template() const {
    return IsTaggedTemplateField::decode(bit_field_);
  }

1615 1616 1617 1618
  bool is_optional_chain_link() const {
    return IsOptionalChainLinkField::decode(bit_field_);
  }

1619
  bool only_last_arg_is_spread() {
1620
    return !arguments_.is_empty() && arguments_.last()->IsSpread();
1621 1622
  }

1623 1624
  enum CallType {
    GLOBAL_CALL,
1625
    WITH_CALL,
1626 1627
    NAMED_PROPERTY_CALL,
    KEYED_PROPERTY_CALL,
1628 1629
    NAMED_OPTIONAL_CHAIN_PROPERTY_CALL,
    KEYED_OPTIONAL_CHAIN_PROPERTY_CALL,
1630 1631
    NAMED_SUPER_PROPERTY_CALL,
    KEYED_SUPER_PROPERTY_CALL,
1632
    PRIVATE_CALL,
1633
    PRIVATE_OPTIONAL_CHAIN_CALL,
1634
    SUPER_CALL,
1635
    OTHER_CALL,
1636 1637
  };

1638 1639 1640 1641 1642
  enum PossiblyEval {
    IS_POSSIBLY_EVAL,
    NOT_EVAL,
  };

1643
  // Helpers to determine how to handle the call.
1644
  CallType GetCallType() const;
1645

1646 1647
  enum class TaggedTemplateTag { kTrue };

1648 1649 1650
 private:
  friend class AstNodeFactory;

1651 1652
  Call(Zone* zone, Expression* expression,
       const ScopedPtrList<Expression>& arguments, int pos,
1653
       PossiblyEval possibly_eval, bool optional_chain)
1654 1655 1656
      : Expression(pos, kCall),
        expression_(expression),
        arguments_(0, nullptr) {
1657
    bit_field_ |=
1658
        IsPossiblyEvalField::encode(possibly_eval == IS_POSSIBLY_EVAL) |
1659 1660
        IsTaggedTemplateField::encode(false) |
        IsOptionalChainLinkField::encode(optional_chain);
1661
    arguments.CopyTo(&arguments_, zone);
1662 1663
  }

1664 1665 1666
  Call(Zone* zone, Expression* expression,
       const ScopedPtrList<Expression>& arguments, int pos,
       TaggedTemplateTag tag)
1667 1668 1669
      : Expression(pos, kCall),
        expression_(expression),
        arguments_(0, nullptr) {
1670
    bit_field_ |= IsPossiblyEvalField::encode(false) |
1671 1672
                  IsTaggedTemplateField::encode(true) |
                  IsOptionalChainLinkField::encode(false);
1673
    arguments.CopyTo(&arguments_, zone);
verwaest@chromium.org's avatar
verwaest@chromium.org committed
1674
  }
1675

1676 1677
  using IsPossiblyEvalField = Expression::NextBitField<bool, 1>;
  using IsTaggedTemplateField = IsPossiblyEvalField::Next<bool, 1>;
1678
  using IsOptionalChainLinkField = IsTaggedTemplateField::Next<bool, 1>;
1679

1680
  Expression* expression_;
1681
  ZonePtrList<Expression> arguments_;
1682
};
1683

1684

1685
class CallNew final : public Expression {
1686
 public:
1687
  Expression* expression() const { return expression_; }
1688
  const ZonePtrList<Expression>* arguments() const { return &arguments_; }
1689

1690
  bool only_last_arg_is_spread() {
1691
    return !arguments_.is_empty() && arguments_.last()->IsSpread();
1692 1693
  }

1694 1695 1696
 private:
  friend class AstNodeFactory;

1697 1698
  CallNew(Zone* zone, Expression* expression,
          const ScopedPtrList<Expression>& arguments, int pos)
1699
      : Expression(pos, kCallNew),
1700
        expression_(expression),
1701
        arguments_(0, nullptr) {
1702
    arguments.CopyTo(&arguments_, zone);
1703
  }
1704

1705
  Expression* expression_;
1706
  ZonePtrList<Expression> arguments_;
1707 1708
};

1709 1710 1711
// The CallRuntime class does not represent any official JavaScript
// language construct. Instead it is used to call a C or JS function
// with a set of arguments. This is used from the builtins that are
1712
// implemented in JavaScript.
1713
class CallRuntime final : public Expression {
1714
 public:
1715
  const ZonePtrList<Expression>* arguments() const { return &arguments_; }
1716
  bool is_jsruntime() const { return function_ == nullptr; }
1717

1718 1719 1720
  int context_index() const {
    DCHECK(is_jsruntime());
    return context_index_;
1721
  }
1722 1723 1724
  const Runtime::Function* function() const {
    DCHECK(!is_jsruntime());
    return function_;
1725 1726
  }

1727
  const char* debug_name();
1728

1729 1730 1731
 private:
  friend class AstNodeFactory;

1732
  CallRuntime(Zone* zone, const Runtime::Function* function,
1733
              const ScopedPtrList<Expression>& arguments, int pos)
1734
      : Expression(pos, kCallRuntime),
1735
        function_(function),
1736
        arguments_(0, nullptr) {
1737
    arguments.CopyTo(&arguments_, zone);
1738
  }
1739 1740
  CallRuntime(Zone* zone, int context_index,
              const ScopedPtrList<Expression>& arguments, int pos)
1741
      : Expression(pos, kCallRuntime),
1742
        context_index_(context_index),
1743
        function_(nullptr),
1744
        arguments_(0, nullptr) {
1745
    arguments.CopyTo(&arguments_, zone);
1746
  }
1747 1748

  int context_index_;
1749
  const Runtime::Function* function_;
1750
  ZonePtrList<Expression> arguments_;
1751 1752 1753
};


1754
class UnaryOperation final : public Expression {
1755
 public:
1756
  Token::Value op() const { return OperatorField::decode(bit_field_); }
1757 1758
  Expression* expression() const { return expression_; }

1759 1760 1761
 private:
  friend class AstNodeFactory;

1762
  UnaryOperation(Token::Value op, Expression* expression, int pos)
1763 1764
      : Expression(pos, kUnaryOperation), expression_(expression) {
    bit_field_ |= OperatorField::encode(op);
1765
    DCHECK(Token::IsUnaryOp(op));
1766
  }
1767

1768
  Expression* expression_;
1769

1770
  using OperatorField = Expression::NextBitField<Token::Value, 7>;
1771 1772 1773
};


1774
class BinaryOperation final : public Expression {
1775
 public:
1776
  Token::Value op() const { return OperatorField::decode(bit_field_); }
1777 1778 1779
  Expression* left() const { return left_; }
  Expression* right() const { return right_; }

1780 1781
  // Returns true if one side is a Smi literal, returning the other side's
  // sub-expression in |subexpr| and the literal Smi in |literal|.
1782
  bool IsSmiLiteralOperation(Expression** subexpr, Smi* literal);
1783

1784 1785 1786
 private:
  friend class AstNodeFactory;

1787
  BinaryOperation(Token::Value op, Expression* left, Expression* right, int pos)
1788
      : Expression(pos, kBinaryOperation), left_(left), right_(right) {
1789
    bit_field_ |= OperatorField::encode(op);
1790
    DCHECK(Token::IsBinaryOp(op));
1791
  }
1792

1793 1794
  Expression* left_;
  Expression* right_;
1795

1796
  using OperatorField = Expression::NextBitField<Token::Value, 7>;
1797 1798
};

1799 1800 1801 1802 1803
class NaryOperation final : public Expression {
 public:
  Token::Value op() const { return OperatorField::decode(bit_field_); }
  Expression* first() const { return first_; }
  Expression* subsequent(size_t index) const {
1804
    return subsequent_[index].expression;
1805 1806
  }

1807
  size_t subsequent_length() const { return subsequent_.size(); }
1808
  int subsequent_op_position(size_t index) const {
1809
    return subsequent_[index].op_position;
1810 1811 1812 1813 1814 1815 1816 1817 1818 1819
  }

  void AddSubsequent(Expression* expr, int pos) {
    subsequent_.emplace_back(expr, pos);
  }

 private:
  friend class AstNodeFactory;

  NaryOperation(Zone* zone, Token::Value op, Expression* first,
1820
                size_t initial_subsequent_size)
1821
      : Expression(first->position(), kNaryOperation),
1822 1823 1824 1825 1826
        first_(first),
        subsequent_(zone) {
    bit_field_ |= OperatorField::encode(op);
    DCHECK(Token::IsBinaryOp(op));
    DCHECK_NE(op, Token::EXP);
1827
    subsequent_.reserve(initial_subsequent_size);
1828 1829
  }

1830 1831 1832 1833
  // Nary operations store the first (lhs) child expression inline, and the
  // child expressions (rhs of each op) are stored out-of-line, along with
  // their operation's position. Note that the Nary operation expression's
  // position has no meaning.
1834 1835 1836
  //
  // So an nary add:
  //
1837
  //    expr + expr + expr + ...
1838 1839 1840
  //
  // is stored as:
  //
1841 1842 1843
  //    (expr) [(+ expr), (+ expr), ...]
  //    '-.--' '-----------.-----------'
  //    first    subsequent entry list
1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854

  Expression* first_;

  struct NaryOperationEntry {
    Expression* expression;
    int op_position;
    NaryOperationEntry(Expression* e, int pos)
        : expression(e), op_position(pos) {}
  };
  ZoneVector<NaryOperationEntry> subsequent_;

1855
  using OperatorField = Expression::NextBitField<Token::Value, 7>;
1856
};
1857

1858
class CountOperation final : public Expression {
1859
 public:
1860 1861
  bool is_prefix() const { return IsPrefixField::decode(bit_field_); }
  bool is_postfix() const { return !is_prefix(); }
1862

1863
  Token::Value op() const { return TokenField::decode(bit_field_); }
1864

1865
  Expression* expression() const { return expression_; }
1866

1867 1868 1869
 private:
  friend class AstNodeFactory;

1870
  CountOperation(Token::Value op, bool is_prefix, Expression* expr, int pos)
1871
      : Expression(pos, kCountOperation), expression_(expr) {
1872
    bit_field_ |= IsPrefixField::encode(is_prefix) | TokenField::encode(op);
1873
  }
1874

1875 1876
  using IsPrefixField = Expression::NextBitField<bool, 1>;
  using TokenField = IsPrefixField::Next<Token::Value, 7>;
1877

1878
  Expression* expression_;
1879 1880 1881
};


1882
class CompareOperation final : public Expression {
1883
 public:
1884
  Token::Value op() const { return OperatorField::decode(bit_field_); }
1885 1886 1887
  Expression* left() const { return left_; }
  Expression* right() const { return right_; }

1888
  // Match special cases.
1889
  bool IsLiteralCompareTypeof(Expression** expr, Literal** literal);
1890
  bool IsLiteralCompareUndefined(Expression** expr);
1891
  bool IsLiteralCompareNull(Expression** expr);
1892

1893 1894 1895
 private:
  friend class AstNodeFactory;

1896 1897
  CompareOperation(Token::Value op, Expression* left, Expression* right,
                   int pos)
1898
      : Expression(pos, kCompareOperation), left_(left), right_(right) {
1899
    bit_field_ |= OperatorField::encode(op);
1900
    DCHECK(Token::IsCompareOp(op));
1901
  }
1902

1903 1904
  Expression* left_;
  Expression* right_;
1905

1906
  using OperatorField = Expression::NextBitField<Token::Value, 7>;
1907 1908 1909
};


1910
class Spread final : public Expression {
1911 1912 1913
 public:
  Expression* expression() const { return expression_; }

nikolaos's avatar
nikolaos committed
1914 1915
  int expression_position() const { return expr_pos_; }

1916 1917 1918
 private:
  friend class AstNodeFactory;

1919 1920
  Spread(Expression* expression, int pos, int expr_pos)
      : Expression(pos, kSpread),
1921 1922
        expr_pos_(expr_pos),
        expression_(expression) {}
1923

nikolaos's avatar
nikolaos committed
1924
  int expr_pos_;
1925
  Expression* expression_;
1926 1927
};

1928
class Conditional final : public Expression {
1929
 public:
1930 1931 1932 1933
  Expression* condition() const { return condition_; }
  Expression* then_expression() const { return then_expression_; }
  Expression* else_expression() const { return else_expression_; }

1934 1935 1936
 private:
  friend class AstNodeFactory;

1937
  Conditional(Expression* condition, Expression* then_expression,
1938
              Expression* else_expression, int position)
1939
      : Expression(position, kConditional),
1940
        condition_(condition),
1941
        then_expression_(then_expression),
1942
        else_expression_(else_expression) {}
1943

1944 1945 1946 1947 1948
  Expression* condition_;
  Expression* then_expression_;
  Expression* else_expression_;
};

1949
class Assignment : public Expression {
1950
 public:
1951
  Token::Value op() const { return TokenField::decode(bit_field_); }
1952 1953
  Expression* target() const { return target_; }
  Expression* value() const { return value_; }
1954

1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966
  // The assignment was generated as part of block-scoped sloppy-mode
  // function hoisting, see
  // ES#sec-block-level-function-declarations-web-legacy-compatibility-semantics
  LookupHoistingMode lookup_hoisting_mode() const {
    return static_cast<LookupHoistingMode>(
        LookupHoistingModeField::decode(bit_field_));
  }
  void set_lookup_hoisting_mode(LookupHoistingMode mode) {
    bit_field_ =
        LookupHoistingModeField::update(bit_field_, static_cast<bool>(mode));
  }

1967 1968 1969 1970
 protected:
  Assignment(NodeType type, Token::Value op, Expression* target,
             Expression* value, int pos);

1971 1972 1973
 private:
  friend class AstNodeFactory;

1974 1975
  using TokenField = Expression::NextBitField<Token::Value, 7>;
  using LookupHoistingModeField = TokenField::Next<bool, 1>;
1976

1977 1978
  Expression* target_;
  Expression* value_;
1979 1980
};

1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994
class CompoundAssignment final : public Assignment {
 public:
  BinaryOperation* binary_operation() const { return binary_operation_; }

 private:
  friend class AstNodeFactory;

  CompoundAssignment(Token::Value op, Expression* target, Expression* value,
                     int pos, BinaryOperation* binary_operation)
      : Assignment(kCompoundAssignment, op, target, value, pos),
        binary_operation_(binary_operation) {}

  BinaryOperation* binary_operation_;
};
1995

1996 1997 1998 1999 2000 2001
// There are several types of Suspend node:
//
// Yield
// YieldStar
// Await
//
2002 2003 2004
// Our Yield is different from the JS yield in that it "returns" its argument as
// is, without wrapping it in an iterator result object.  Such wrapping, if
// desired, must be done beforehand (see the parser).
2005
class Suspend : public Expression {
2006
 public:
2007 2008 2009
  // With {kNoControl}, the {Suspend} behaves like yield, except that it never
  // throws and never causes the current generator to return. This is used to
  // desugar yield*.
2010 2011 2012
  // TODO(caitp): remove once yield* desugaring for async generators is handled
  // in BytecodeGenerator.
  enum OnAbruptResume { kOnExceptionThrow, kNoControl };
2013

2014
  Expression* expression() const { return expression_; }
2015 2016
  OnAbruptResume on_abrupt_resume() const {
    return OnAbruptResumeField::decode(bit_field_);
2017
  }
2018

2019 2020
 private:
  friend class AstNodeFactory;
2021
  friend class Yield;
2022
  friend class YieldStar;
2023
  friend class Await;
2024

2025
  Suspend(NodeType node_type, Expression* expression, int pos,
2026
          OnAbruptResume on_abrupt_resume)
2027
      : Expression(pos, node_type), expression_(expression) {
2028
    bit_field_ |= OnAbruptResumeField::encode(on_abrupt_resume);
2029
  }
2030

2031
  Expression* expression_;
2032

2033
  using OnAbruptResumeField = Expression::NextBitField<OnAbruptResume, 1>;
2034 2035 2036 2037 2038 2039
};

class Yield final : public Suspend {
 private:
  friend class AstNodeFactory;
  Yield(Expression* expression, int pos, OnAbruptResume on_abrupt_resume)
2040
      : Suspend(kYield, expression, pos, on_abrupt_resume) {}
2041 2042
};

2043 2044 2045
class YieldStar final : public Suspend {
 private:
  friend class AstNodeFactory;
2046
  YieldStar(Expression* expression, int pos)
2047
      : Suspend(kYieldStar, expression, pos,
2048
                Suspend::OnAbruptResume::kNoControl) {}
2049
};
2050

2051 2052 2053 2054
class Await final : public Suspend {
 private:
  friend class AstNodeFactory;

2055
  Await(Expression* expression, int pos)
2056
      : Suspend(kAwait, expression, pos, Suspend::kOnExceptionThrow) {}
2057 2058
};

2059
class Throw final : public Expression {
2060 2061
 public:
  Expression* exception() const { return exception_; }
2062

2063 2064 2065
 private:
  friend class AstNodeFactory;

2066 2067
  Throw(Expression* exception, int pos)
      : Expression(pos, kThrow), exception_(exception) {}
2068 2069 2070 2071 2072

  Expression* exception_;
};


2073
class FunctionLiteral final : public Expression {
2074
 public:
2075 2076 2077 2078 2079
  enum ParameterFlag : uint8_t {
    kNoDuplicateParameters,
    kHasDuplicateParameters
  };
  enum EagerCompileHint : uint8_t { kShouldEagerCompile, kShouldLazyCompile };
2080

2081 2082
  // Empty handle means that the function does not have a shared name (i.e.
  // the name will be set dynamically after creation of the function closure).
2083 2084 2085
  template <typename LocalIsolate>
  MaybeHandle<String> GetName(LocalIsolate* isolate) const {
    return raw_name_ ? raw_name_->AllocateFlat(isolate) : MaybeHandle<String>();
2086 2087
  }
  bool has_shared_name() const { return raw_name_ != nullptr; }
2088 2089
  const AstConsString* raw_name() const { return raw_name_; }
  void set_raw_name(const AstConsString* name) { raw_name_ = name; }
2090
  DeclarationScope* scope() const { return scope_; }
2091
  ZonePtrList<Statement>* body() { return &body_; }
2092 2093
  void set_function_token_position(int pos) { function_token_position_ = pos; }
  int function_token_position() const { return function_token_position_; }
2094 2095
  int start_position() const;
  int end_position() const;
2096
  bool is_anonymous_expression() const {
2097
    return syntax_kind() == FunctionSyntaxKind::kAnonymousExpression;
2098
  }
2099

2100 2101 2102 2103
  void mark_as_oneshot_iife() {
    bit_field_ = OneshotIIFEBit::update(bit_field_, true);
  }
  bool is_oneshot_iife() const { return OneshotIIFEBit::decode(bit_field_); }
2104
  bool is_toplevel() const {
2105
    return function_literal_id() == kFunctionLiteralIdTopLevel;
2106
  }
2107
  V8_EXPORT_PRIVATE LanguageMode language_mode() const;
2108

2109
  static bool NeedsHomeObject(Expression* expr);
2110

2111 2112
  void add_expected_properties(int number_properties) {
    expected_property_count_ += number_properties;
2113
  }
2114
  int expected_property_count() { return expected_property_count_; }
2115
  int parameter_count() { return parameter_count_; }
2116
  int function_length() { return function_length_; }
2117 2118 2119

  bool AllowsLazyCompilation();

2120 2121 2122 2123 2124 2125 2126 2127
  bool CanSuspend() {
    if (suspend_count() > 0) {
      DCHECK(IsResumableFunction(kind()));
      return true;
    }
    return false;
  }

2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139
  // We can safely skip the arguments adaptor frame setup even
  // in case of arguments mismatches for strict mode functions,
  // as long as there's
  //
  //   1. no use of the arguments object (either explicitly or
  //      potentially implicitly via a direct eval() call), and
  //   2. rest parameters aren't being used in the function.
  //
  // See http://bit.ly/v8-faster-calls-with-arguments-mismatch
  // for the details here (https://crbug.com/v8/8895).
  bool SafeToSkipArgumentsAdaptor() const;

2140 2141
  // Returns either name or inferred name as a cstring.
  std::unique_ptr<char[]> GetDebugName() const;
2142

2143
  Handle<String> GetInferredName(Isolate* isolate) {
2144
    if (!inferred_name_.is_null()) {
2145
      DCHECK_NULL(raw_inferred_name_);
2146 2147
      return inferred_name_;
    }
2148
    if (raw_inferred_name_ != nullptr) {
2149
      return raw_inferred_name_->GetString(isolate);
2150 2151 2152
    }
    UNREACHABLE();
  }
2153
  Handle<String> GetInferredName(OffThreadIsolate* isolate) const {
2154 2155 2156 2157
    DCHECK(inferred_name_.is_null());
    DCHECK_NOT_NULL(raw_inferred_name_);
    return raw_inferred_name_->GetString(isolate);
  }
2158 2159
  const AstConsString* raw_inferred_name() { return raw_inferred_name_; }

2160 2161
  // Only one of {set_inferred_name, set_raw_inferred_name} should be called.
  void set_inferred_name(Handle<String> inferred_name);
2162
  void set_raw_inferred_name(AstConsString* raw_inferred_name);
2163

2164 2165
  bool pretenure() const { return Pretenure::decode(bit_field_); }
  void set_pretenure() { bit_field_ = Pretenure::update(bit_field_, true); }
2166

2167
  bool has_duplicate_parameters() const {
2168
    // Not valid for lazy functions.
2169
    DCHECK(ShouldEagerCompile());
2170
    return HasDuplicateParameters::decode(bit_field_);
2171
  }
2172

2173 2174 2175 2176 2177
  // This is used as a heuristic on when to eagerly compile a function
  // literal. We consider the following constructs as hints that the
  // function will be called immediately:
  // - (function() { ... })();
  // - var x = function() { ... }();
2178
  V8_EXPORT_PRIVATE bool ShouldEagerCompile() const;
2179
  V8_EXPORT_PRIVATE void SetShouldEagerCompile();
2180

2181 2182
  FunctionSyntaxKind syntax_kind() const {
    return FunctionSyntaxKindBits::decode(bit_field_);
2183
  }
2184
  FunctionKind kind() const;
2185

2186 2187 2188
  bool dont_optimize() {
    return dont_optimize_reason() != BailoutReason::kNoReason;
  }
2189
  BailoutReason dont_optimize_reason() {
2190
    return DontOptimizeReasonField::decode(bit_field_);
2191
  }
2192
  void set_dont_optimize_reason(BailoutReason reason) {
2193
    bit_field_ = DontOptimizeReasonField::update(bit_field_, reason);
2194 2195
  }

2196
  bool IsAnonymousFunctionDefinition() const {
2197
    return is_anonymous_expression();
2198 2199
  }

2200 2201
  int suspend_count() { return suspend_count_; }
  void set_suspend_count(int suspend_count) { suspend_count_ = suspend_count; }
2202

2203
  int return_position() {
2204 2205 2206
    return std::max(
        start_position(),
        end_position() - (HasBracesField::decode(bit_field_) ? 1 : 0));
2207 2208
  }

2209 2210 2211 2212 2213
  int function_literal_id() const { return function_literal_id_; }
  void set_function_literal_id(int function_literal_id) {
    function_literal_id_ = function_literal_id;
  }

2214 2215
  void set_requires_instance_members_initializer(bool value) {
    bit_field_ = RequiresInstanceMembersInitializer::update(bit_field_, value);
2216
  }
2217 2218
  bool requires_instance_members_initializer() const {
    return RequiresInstanceMembersInitializer::decode(bit_field_);
2219 2220
  }

2221 2222 2223 2224 2225 2226 2227 2228
  void set_has_static_private_methods_or_accessors(bool value) {
    bit_field_ =
        HasStaticPrivateMethodsOrAccessorsField::update(bit_field_, value);
  }
  bool has_static_private_methods_or_accessors() const {
    return HasStaticPrivateMethodsOrAccessorsField::decode(bit_field_);
  }

2229 2230 2231 2232 2233 2234
  void set_class_scope_has_private_brand(bool value) {
    bit_field_ = ClassScopeHasPrivateBrandField::update(bit_field_, value);
  }
  bool class_scope_has_private_brand() const {
    return ClassScopeHasPrivateBrandField::decode(bit_field_);
  }
2235

2236 2237
  bool private_name_lookup_skips_outer_class() const;

2238 2239
  ProducedPreparseData* produced_preparse_data() const {
    return produced_preparse_data_;
2240 2241
  }

2242 2243 2244
 private:
  friend class AstNodeFactory;

2245
  FunctionLiteral(Zone* zone, const AstConsString* name,
2246 2247 2248
                  AstValueFactory* ast_value_factory, DeclarationScope* scope,
                  const ScopedPtrList<Statement>& body,
                  int expected_property_count, int parameter_count,
2249
                  int function_length, FunctionSyntaxKind function_syntax_kind,
2250 2251 2252 2253
                  ParameterFlag has_duplicate_parameters,
                  EagerCompileHint eager_compile_hint, int position,
                  bool has_braces, int function_literal_id,
                  ProducedPreparseData* produced_preparse_data = nullptr)
2254
      : Expression(position, kFunctionLiteral),
2255 2256
        expected_property_count_(expected_property_count),
        parameter_count_(parameter_count),
2257
        function_length_(function_length),
yangguo's avatar
yangguo committed
2258
        function_token_position_(kNoSourcePosition),
2259
        suspend_count_(0),
2260
        function_literal_id_(function_literal_id),
2261
        raw_name_(name),
2262
        scope_(scope),
2263
        body_(0, nullptr),
2264
        raw_inferred_name_(ast_value_factory->empty_cons_string()),
2265
        produced_preparse_data_(produced_preparse_data) {
2266 2267 2268 2269 2270 2271 2272 2273
    bit_field_ |= FunctionSyntaxKindBits::encode(function_syntax_kind) |
                  Pretenure::encode(false) |
                  HasDuplicateParameters::encode(has_duplicate_parameters ==
                                                 kHasDuplicateParameters) |
                  DontOptimizeReasonField::encode(BailoutReason::kNoReason) |
                  RequiresInstanceMembersInitializer::encode(false) |
                  HasBracesField::encode(has_braces) |
                  OneshotIIFEBit::encode(false);
2274
    if (eager_compile_hint == kShouldEagerCompile) SetShouldEagerCompile();
2275
    body.CopyTo(&body_, zone);
2276
  }
2277

2278 2279 2280
  using FunctionSyntaxKindBits =
      Expression::NextBitField<FunctionSyntaxKind, 3>;
  using Pretenure = FunctionSyntaxKindBits::Next<bool, 1>;
2281
  using HasDuplicateParameters = Pretenure::Next<bool, 1>;
2282
  using DontOptimizeReasonField =
2283
      HasDuplicateParameters::Next<BailoutReason, 8>;
2284
  using RequiresInstanceMembersInitializer =
2285
      DontOptimizeReasonField::Next<bool, 1>;
2286 2287
  using ClassScopeHasPrivateBrandField =
      RequiresInstanceMembersInitializer::Next<bool, 1>;
2288 2289 2290
  using HasStaticPrivateMethodsOrAccessorsField =
      ClassScopeHasPrivateBrandField::Next<bool, 1>;
  using HasBracesField = HasStaticPrivateMethodsOrAccessorsField::Next<bool, 1>;
2291
  using OneshotIIFEBit = HasBracesField::Next<bool, 1>;
2292

2293 2294
  // expected_property_count_ is the sum of instance fields and properties.
  // It can vary depending on whether a function is lazily or eagerly parsed.
2295
  int expected_property_count_;
2296
  int parameter_count_;
2297
  int function_length_;
2298
  int function_token_position_;
2299
  int suspend_count_;
2300
  int function_literal_id_;
2301

2302
  const AstConsString* raw_name_;
2303
  DeclarationScope* scope_;
2304
  ZonePtrList<Statement> body_;
2305
  AstConsString* raw_inferred_name_;
2306
  Handle<String> inferred_name_;
2307
  ProducedPreparseData* produced_preparse_data_;
2308 2309
};

2310 2311 2312 2313
// Property is used for passing information
// about a class literal's properties from the parser to the code generator.
class ClassLiteralProperty final : public LiteralProperty {
 public:
2314
  enum Kind : uint8_t { METHOD, GETTER, SETTER, FIELD };
2315 2316 2317 2318 2319

  Kind kind() const { return kind_; }

  bool is_static() const { return is_static_; }

2320 2321
  bool is_private() const { return is_private_; }

2322
  void set_computed_name_var(Variable* var) {
2323 2324
    DCHECK_EQ(FIELD, kind());
    DCHECK(!is_private());
2325 2326
    private_or_computed_name_var_ = var;
  }
2327

2328
  Variable* computed_name_var() const {
2329 2330
    DCHECK_EQ(FIELD, kind());
    DCHECK(!is_private());
2331 2332 2333
    return private_or_computed_name_var_;
  }

2334
  void set_private_name_var(Variable* var) {
2335
    DCHECK(is_private());
2336 2337
    private_or_computed_name_var_ = var;
  }
2338
  Variable* private_name_var() const {
2339
    DCHECK(is_private());
2340 2341
    return private_or_computed_name_var_;
  }
2342

2343 2344 2345 2346 2347
  bool NeedsHomeObjectOnClassPrototype() const {
    return is_private() && kind_ == METHOD &&
           FunctionLiteral::NeedsHomeObject(value_);
  }

2348 2349 2350 2351
 private:
  friend class AstNodeFactory;

  ClassLiteralProperty(Expression* key, Expression* value, Kind kind,
2352
                       bool is_static, bool is_computed_name, bool is_private);
2353 2354 2355

  Kind kind_;
  bool is_static_;
2356
  bool is_private_;
2357
  Variable* private_or_computed_name_var_;
2358
};
2359

2360
class InitializeClassMembersStatement final : public Statement {
2361
 public:
2362
  using Property = ClassLiteralProperty;
2363 2364

  ZonePtrList<Property>* fields() const { return fields_; }
2365 2366 2367 2368

 private:
  friend class AstNodeFactory;

2369 2370
  InitializeClassMembersStatement(ZonePtrList<Property>* fields, int pos)
      : Statement(pos, kInitializeClassMembersStatement), fields_(fields) {}
2371

2372
  ZonePtrList<Property>* fields_;
2373 2374
};

2375
class ClassLiteral final : public Expression {
arv@chromium.org's avatar
arv@chromium.org committed
2376
 public:
2377
  using Property = ClassLiteralProperty;
arv@chromium.org's avatar
arv@chromium.org committed
2378

2379
  ClassScope* scope() const { return scope_; }
arv@chromium.org's avatar
arv@chromium.org committed
2380
  Expression* extends() const { return extends_; }
2381
  FunctionLiteral* constructor() const { return constructor_; }
2382 2383
  ZonePtrList<Property>* public_members() const { return public_members_; }
  ZonePtrList<Property>* private_members() const { return private_members_; }
2384 2385
  int start_position() const { return position(); }
  int end_position() const { return end_position_; }
2386 2387 2388 2389 2390 2391
  bool has_name_static_property() const {
    return HasNameStaticProperty::decode(bit_field_);
  }
  bool has_static_computed_names() const {
    return HasStaticComputedNames::decode(bit_field_);
  }
arv@chromium.org's avatar
arv@chromium.org committed
2392

2393 2394 2395
  bool is_anonymous_expression() const {
    return IsAnonymousExpression::decode(bit_field_);
  }
2396 2397 2398
  bool has_private_methods() const {
    return HasPrivateMethods::decode(bit_field_);
  }
2399 2400 2401 2402
  bool IsAnonymousFunctionDefinition() const {
    return is_anonymous_expression();
  }

2403 2404 2405 2406
  FunctionLiteral* static_fields_initializer() const {
    return static_fields_initializer_;
  }

2407 2408
  FunctionLiteral* instance_members_initializer_function() const {
    return instance_members_initializer_function_;
2409 2410
  }

2411 2412
 private:
  friend class AstNodeFactory;
2413

2414
  ClassLiteral(ClassScope* scope, Expression* extends,
2415 2416 2417
               FunctionLiteral* constructor,
               ZonePtrList<Property>* public_members,
               ZonePtrList<Property>* private_members,
2418
               FunctionLiteral* static_fields_initializer,
2419
               FunctionLiteral* instance_members_initializer_function,
2420 2421
               int start_position, int end_position,
               bool has_name_static_property, bool has_static_computed_names,
2422
               bool is_anonymous, bool has_private_methods)
2423
      : Expression(start_position, kClassLiteral),
2424
        end_position_(end_position),
2425
        scope_(scope),
arv@chromium.org's avatar
arv@chromium.org committed
2426 2427
        extends_(extends),
        constructor_(constructor),
2428 2429
        public_members_(public_members),
        private_members_(private_members),
2430
        static_fields_initializer_(static_fields_initializer),
2431 2432
        instance_members_initializer_function_(
            instance_members_initializer_function) {
2433
    bit_field_ |= HasNameStaticProperty::encode(has_name_static_property) |
2434
                  HasStaticComputedNames::encode(has_static_computed_names) |
2435 2436
                  IsAnonymousExpression::encode(is_anonymous) |
                  HasPrivateMethods::encode(has_private_methods);
2437
  }
2438

2439
  int end_position_;
2440
  ClassScope* scope_;
arv@chromium.org's avatar
arv@chromium.org committed
2441
  Expression* extends_;
2442
  FunctionLiteral* constructor_;
2443 2444
  ZonePtrList<Property>* public_members_;
  ZonePtrList<Property>* private_members_;
2445
  FunctionLiteral* static_fields_initializer_;
2446
  FunctionLiteral* instance_members_initializer_function_;
2447 2448 2449
  using HasNameStaticProperty = Expression::NextBitField<bool, 1>;
  using HasStaticComputedNames = HasNameStaticProperty::Next<bool, 1>;
  using IsAnonymousExpression = HasStaticComputedNames::Next<bool, 1>;
2450
  using HasPrivateMethods = IsAnonymousExpression::Next<bool, 1>;
arv@chromium.org's avatar
arv@chromium.org committed
2451 2452 2453
};


2454
class NativeFunctionLiteral final : public Expression {
2455
 public:
2456
  Handle<String> name() const { return name_->string(); }
2457
  const AstRawString* raw_name() const { return name_; }
2458
  v8::Extension* extension() const { return extension_; }
2459

2460 2461 2462
 private:
  friend class AstNodeFactory;

2463 2464 2465
  NativeFunctionLiteral(const AstRawString* name, v8::Extension* extension,
                        int pos)
      : Expression(pos, kNativeFunctionLiteral),
2466 2467
        name_(name),
        extension_(extension) {}
2468

2469
  const AstRawString* name_;
2470
  v8::Extension* extension_;
2471 2472 2473
};


2474
class SuperPropertyReference final : public Expression {
2475
 public:
2476
  Expression* home_object() const { return home_object_; }
2477

2478 2479 2480
 private:
  friend class AstNodeFactory;

2481 2482 2483
  // We take in ThisExpression* only as a proof that it was accessed.
  SuperPropertyReference(Expression* home_object, int pos)
      : Expression(pos, kSuperPropertyReference), home_object_(home_object) {
2484
    DCHECK(home_object->IsProperty());
2485
  }
2486

2487
  Expression* home_object_;
2488 2489 2490
};


2491 2492 2493 2494 2495
class SuperCallReference final : public Expression {
 public:
  VariableProxy* new_target_var() const { return new_target_var_; }
  VariableProxy* this_function_var() const { return this_function_var_; }

2496 2497 2498
 private:
  friend class AstNodeFactory;

2499 2500
  // We take in ThisExpression* only as a proof that it was accessed.
  SuperCallReference(VariableProxy* new_target_var,
2501
                     VariableProxy* this_function_var, int pos)
2502
      : Expression(pos, kSuperCallReference),
2503 2504
        new_target_var_(new_target_var),
        this_function_var_(this_function_var) {
2505
    DCHECK(new_target_var->raw_name()->IsOneByteEqualTo(".new.target"));
2506 2507 2508 2509 2510 2511 2512
    DCHECK(this_function_var->raw_name()->IsOneByteEqualTo(".this_function"));
  }

  VariableProxy* new_target_var_;
  VariableProxy* this_function_var_;
};

2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526
// This AST Node is used to represent a dynamic import call --
// import(argument).
class ImportCallExpression final : public Expression {
 public:
  Expression* argument() const { return argument_; }

 private:
  friend class AstNodeFactory;

  ImportCallExpression(Expression* argument, int pos)
      : Expression(pos, kImportCallExpression), argument_(argument) {}

  Expression* argument_;
};
2527

2528 2529 2530 2531
// This class is produced when parsing the () in arrow functions without any
// arguments and is not actually a valid expression.
class EmptyParentheses final : public Expression {
 private:
2532 2533
  friend class AstNodeFactory;

2534 2535 2536
  explicit EmptyParentheses(int pos) : Expression(pos, kEmptyParentheses) {
    mark_parenthesized();
  }
2537 2538
};

2539 2540 2541 2542
// Represents the spec operation `GetTemplateObject(templateLiteral)`
// (defined at https://tc39.github.io/ecma262/#sec-gettemplateobject).
class GetTemplateObject final : public Expression {
 public:
2543
  const ZonePtrList<const AstRawString>* cooked_strings() const {
2544 2545
    return cooked_strings_;
  }
2546
  const ZonePtrList<const AstRawString>* raw_strings() const {
2547 2548
    return raw_strings_;
  }
2549

2550 2551 2552
  template <typename LocalIsolate>
  Handle<TemplateObjectDescription> GetOrBuildDescription(
      LocalIsolate* isolate);
2553 2554 2555 2556

 private:
  friend class AstNodeFactory;

2557 2558
  GetTemplateObject(const ZonePtrList<const AstRawString>* cooked_strings,
                    const ZonePtrList<const AstRawString>* raw_strings, int pos)
2559 2560
      : Expression(pos, kGetTemplateObject),
        cooked_strings_(cooked_strings),
2561
        raw_strings_(raw_strings) {}
2562

2563 2564
  const ZonePtrList<const AstRawString>* cooked_strings_;
  const ZonePtrList<const AstRawString>* raw_strings_;
2565 2566
};

2567 2568
class TemplateLiteral final : public Expression {
 public:
2569 2570 2571 2572 2573 2574
  const ZonePtrList<const AstRawString>* string_parts() const {
    return string_parts_;
  }
  const ZonePtrList<Expression>* substitutions() const {
    return substitutions_;
  }
2575 2576 2577

 private:
  friend class AstNodeFactory;
2578 2579
  TemplateLiteral(const ZonePtrList<const AstRawString>* parts,
                  const ZonePtrList<Expression>* substitutions, int pos)
2580 2581 2582 2583
      : Expression(pos, kTemplateLiteral),
        string_parts_(parts),
        substitutions_(substitutions) {}

2584 2585
  const ZonePtrList<const AstRawString>* string_parts_;
  const ZonePtrList<Expression>* substitutions_;
2586 2587
};

2588 2589
// ----------------------------------------------------------------------------
// Basic visitor
2590 2591
// Sub-class should parametrize AstVisitor with itself, e.g.:
//   class SpecificVisitor : public AstVisitor<SpecificVisitor> { ... }
2592

2593
template <class Subclass>
2594
class AstVisitor {
2595
 public:
2596
  void Visit(AstNode* node) { impl()->Visit(node); }
2597

2598 2599
  void VisitDeclarations(Declaration::List* declarations) {
    for (Declaration* decl : *declarations) Visit(decl);
2600
  }
2601

2602
  void VisitStatements(const ZonePtrList<Statement>* statements) {
2603 2604 2605 2606 2607 2608
    for (int i = 0; i < statements->length(); i++) {
      Statement* stmt = statements->at(i);
      Visit(stmt);
    }
  }

2609
  void VisitExpressions(const ZonePtrList<Expression>* expressions) {
2610
    for (int i = 0; i < expressions->length(); i++) {
2611
      // The variable statement visiting code may pass null expressions
2612
      // to this code. Maybe this should be handled by introducing an
2613 2614
      // undefined expression or literal? Revisit this code if this
      // changes.
2615
      Expression* expression = expressions->at(i);
2616
      if (expression != nullptr) Visit(expression);
2617 2618
    }
  }
2619

2620 2621
 protected:
  Subclass* impl() { return static_cast<Subclass*>(this); }
2622
};
2623

2624 2625 2626
#define GENERATE_VISIT_CASE(NodeType)                                   \
  case AstNode::k##NodeType:                                            \
    return this->impl()->Visit##NodeType(static_cast<NodeType*>(node));
2627

2628 2629 2630 2631 2632 2633 2634 2635
#define GENERATE_FAILURE_CASE(NodeType) \
  case AstNode::k##NodeType:            \
    UNREACHABLE();

#define GENERATE_AST_VISITOR_SWITCH()        \
  switch (node->node_type()) {               \
    AST_NODE_LIST(GENERATE_VISIT_CASE)       \
    FAILURE_NODE_LIST(GENERATE_FAILURE_CASE) \
2636 2637
  }

2638 2639
#define DEFINE_AST_VISITOR_SUBCLASS_MEMBERS()               \
 public:                                                    \
2640 2641 2642 2643
  void VisitNoStackOverflowCheck(AstNode* node) {           \
    GENERATE_AST_VISITOR_SWITCH()                           \
  }                                                         \
                                                            \
2644 2645
  void Visit(AstNode* node) {                               \
    if (CheckStackOverflow()) return;                       \
2646
    VisitNoStackOverflowCheck(node);                        \
2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661
  }                                                         \
                                                            \
  void SetStackOverflow() { stack_overflow_ = true; }       \
  void ClearStackOverflow() { stack_overflow_ = false; }    \
  bool HasStackOverflow() const { return stack_overflow_; } \
                                                            \
  bool CheckStackOverflow() {                               \
    if (stack_overflow_) return true;                       \
    if (GetCurrentStackPosition() < stack_limit_) {         \
      stack_overflow_ = true;                               \
      return true;                                          \
    }                                                       \
    return false;                                           \
  }                                                         \
                                                            \
2662 2663 2664
 protected:                                                 \
  uintptr_t stack_limit() const { return stack_limit_; }    \
                                                            \
2665
 private:                                                   \
2666 2667 2668 2669 2670
  void InitializeAstVisitor(Isolate* isolate) {             \
    stack_limit_ = isolate->stack_guard()->real_climit();   \
    stack_overflow_ = false;                                \
  }                                                         \
                                                            \
2671 2672 2673 2674 2675
  void InitializeAstVisitor(uintptr_t stack_limit) {        \
    stack_limit_ = stack_limit;                             \
    stack_overflow_ = false;                                \
  }                                                         \
                                                            \
2676
  uintptr_t stack_limit_;                                   \
2677
  bool stack_overflow_
2678

2679 2680 2681 2682 2683 2684
#define DEFINE_AST_VISITOR_MEMBERS_WITHOUT_STACKOVERFLOW()    \
 public:                                                      \
  void Visit(AstNode* node) { GENERATE_AST_VISITOR_SWITCH() } \
                                                              \
 private:

2685 2686 2687
// ----------------------------------------------------------------------------
// AstNode factory

2688
class AstNodeFactory final {
2689
 public:
2690
  AstNodeFactory(AstValueFactory* ast_value_factory, Zone* zone)
2691 2692
      : zone_(zone),
        ast_value_factory_(ast_value_factory),
2693
        empty_statement_(new (zone) class EmptyStatement()),
2694
        this_expression_(new (zone) class ThisExpression()),
2695
        failure_expression_(new (zone) class FailureExpression()) {}
2696

2697
  AstNodeFactory* ast_node_factory() { return this; }
neis's avatar
neis committed
2698 2699
  AstValueFactory* ast_value_factory() const { return ast_value_factory_; }

2700 2701
  VariableDeclaration* NewVariableDeclaration(int pos) {
    return new (zone_) VariableDeclaration(pos);
2702 2703
  }

2704
  NestedVariableDeclaration* NewNestedVariableDeclaration(Scope* scope,
2705
                                                          int pos) {
2706
    return new (zone_) NestedVariableDeclaration(scope, pos);
2707 2708
  }

2709 2710
  FunctionDeclaration* NewFunctionDeclaration(FunctionLiteral* fun, int pos) {
    return new (zone_) FunctionDeclaration(fun, pos);
2711 2712
  }

2713
  Block* NewBlock(int capacity, bool ignore_completion_value) {
2714
    return new (zone_) Block(zone_, capacity, ignore_completion_value, false);
2715 2716
  }

2717 2718
  Block* NewBlock(bool ignore_completion_value, bool is_breakable) {
    return new (zone_) Block(ignore_completion_value, is_breakable);
2719 2720 2721 2722
  }

  Block* NewBlock(bool ignore_completion_value,
                  const ScopedPtrList<Statement>& statements) {
2723
    Block* result = NewBlock(ignore_completion_value, false);
2724 2725
    result->InitializeStatements(statements, zone_);
    return result;
2726 2727
  }

2728 2729 2730 2731 2732 2733
#define STATEMENT_WITH_POSITION(NodeType) \
  NodeType* New##NodeType(int pos) { return new (zone_) NodeType(pos); }
  STATEMENT_WITH_POSITION(DoWhileStatement)
  STATEMENT_WITH_POSITION(WhileStatement)
  STATEMENT_WITH_POSITION(ForStatement)
#undef STATEMENT_WITH_POSITION
2734

2735 2736
  SwitchStatement* NewSwitchStatement(Expression* tag, int pos) {
    return new (zone_) SwitchStatement(zone_, tag, pos);
2737 2738
  }

2739 2740
  ForEachStatement* NewForEachStatement(ForEachStatement::VisitMode visit_mode,
                                        int pos) {
2741 2742
    switch (visit_mode) {
      case ForEachStatement::ENUMERATE: {
2743
        return new (zone_) ForInStatement(pos);
2744 2745
      }
      case ForEachStatement::ITERATE: {
2746
        return new (zone_) ForOfStatement(pos, IteratorType::kNormal);
2747 2748 2749 2750 2751
      }
    }
    UNREACHABLE();
  }

2752 2753
  ForOfStatement* NewForOfStatement(int pos, IteratorType type) {
    return new (zone_) ForOfStatement(pos, type);
2754 2755
  }

2756
  ExpressionStatement* NewExpressionStatement(Expression* expression, int pos) {
2757
    return new (zone_) ExpressionStatement(expression, pos);
2758 2759
  }

2760 2761
  ContinueStatement* NewContinueStatement(IterationStatement* target, int pos) {
    return new (zone_) ContinueStatement(target, pos);
2762 2763
  }

2764 2765
  BreakStatement* NewBreakStatement(BreakableStatement* target, int pos) {
    return new (zone_) BreakStatement(target, pos);
2766 2767
  }

2768 2769 2770 2771
  ReturnStatement* NewReturnStatement(Expression* expression, int pos,
                                      int end_position = kNoSourcePosition) {
    return new (zone_) ReturnStatement(expression, ReturnStatement::kNormal,
                                       pos, end_position);
2772 2773
  }

2774 2775 2776 2777
  ReturnStatement* NewAsyncReturnStatement(
      Expression* expression, int pos, int end_position = kNoSourcePosition) {
    return new (zone_) ReturnStatement(
        expression, ReturnStatement::kAsyncReturn, pos, end_position);
2778 2779
  }

2780 2781 2782 2783 2784 2785
  ReturnStatement* NewSyntheticAsyncReturnStatement(
      Expression* expression, int pos, int end_position = kNoSourcePosition) {
    return new (zone_) ReturnStatement(
        expression, ReturnStatement::kSyntheticAsyncReturn, pos, end_position);
  }

2786 2787
  WithStatement* NewWithStatement(Scope* scope,
                                  Expression* expression,
2788 2789
                                  Statement* statement,
                                  int pos) {
2790
    return new (zone_) WithStatement(scope, expression, statement, pos);
2791 2792
  }

2793
  IfStatement* NewIfStatement(Expression* condition, Statement* then_statement,
2794 2795 2796
                              Statement* else_statement, int pos) {
    return new (zone_)
        IfStatement(condition, then_statement, else_statement, pos);
2797 2798
  }

2799
  TryCatchStatement* NewTryCatchStatement(Block* try_block, Scope* scope,
2800 2801 2802
                                          Block* catch_block, int pos) {
    return new (zone_) TryCatchStatement(try_block, scope, catch_block,
                                         HandlerTable::CAUGHT, pos);
2803 2804 2805 2806 2807 2808
  }

  TryCatchStatement* NewTryCatchStatementForReThrow(Block* try_block,
                                                    Scope* scope,
                                                    Block* catch_block,
                                                    int pos) {
2809
    return new (zone_) TryCatchStatement(try_block, scope, catch_block,
2810
                                         HandlerTable::UNCAUGHT, pos);
2811 2812
  }

2813 2814 2815 2816
  TryCatchStatement* NewTryCatchStatementForDesugaring(Block* try_block,
                                                       Scope* scope,
                                                       Block* catch_block,
                                                       int pos) {
2817
    return new (zone_) TryCatchStatement(try_block, scope, catch_block,
2818
                                         HandlerTable::DESUGARING, pos);
2819 2820
  }

2821 2822 2823 2824
  TryCatchStatement* NewTryCatchStatementForAsyncAwait(Block* try_block,
                                                       Scope* scope,
                                                       Block* catch_block,
                                                       int pos) {
2825
    return new (zone_) TryCatchStatement(try_block, scope, catch_block,
2826
                                         HandlerTable::ASYNC_AWAIT, pos);
2827 2828
  }

2829 2830 2831 2832 2833 2834 2835 2836
  TryCatchStatement* NewTryCatchStatementForReplAsyncAwait(Block* try_block,
                                                           Scope* scope,
                                                           Block* catch_block,
                                                           int pos) {
    return new (zone_) TryCatchStatement(
        try_block, scope, catch_block, HandlerTable::UNCAUGHT_ASYNC_AWAIT, pos);
  }

2837 2838 2839
  TryFinallyStatement* NewTryFinallyStatement(Block* try_block,
                                              Block* finally_block, int pos) {
    return new (zone_) TryFinallyStatement(try_block, finally_block, pos);
2840 2841
  }

2842
  DebuggerStatement* NewDebuggerStatement(int pos) {
2843
    return new (zone_) DebuggerStatement(pos);
2844 2845
  }

2846 2847
  class EmptyStatement* EmptyStatement() {
    return empty_statement_;
2848 2849
  }

2850
  class ThisExpression* ThisExpression() {
2851 2852 2853 2854 2855 2856 2857
    // Clear any previously set "parenthesized" flag on this_expression_ so this
    // particular token does not inherit the it. The flag is used to check
    // during arrow function head parsing whether we came from parenthesized
    // exprssion parsing, since additional arrow function verification was done
    // there. It does not matter whether a flag is unset after arrow head
    // verification, so clearing at this point is fine.
    this_expression_->clear_parenthesized();
2858 2859 2860
    return this_expression_;
  }

2861 2862 2863 2864
  class FailureExpression* FailureExpression() {
    return failure_expression_;
  }

2865 2866 2867 2868
  SloppyBlockFunctionStatement* NewSloppyBlockFunctionStatement(
      int pos, Variable* var, Token::Value init) {
    return new (zone_)
        SloppyBlockFunctionStatement(pos, var, init, EmptyStatement());
2869 2870
  }

2871
  CaseClause* NewCaseClause(Expression* label,
2872
                            const ScopedPtrList<Statement>& statements) {
2873
    return new (zone_) CaseClause(zone_, label, statements);
2874 2875
  }

2876
  Literal* NewStringLiteral(const AstRawString* string, int pos) {
2877
    DCHECK_NOT_NULL(string);
2878
    return new (zone_) Literal(string, pos);
2879 2880 2881
  }

  // A JavaScript symbol (ECMA-262 edition 6).
2882
  Literal* NewSymbolLiteral(AstSymbol symbol, int pos) {
2883
    return new (zone_) Literal(symbol, pos);
2884 2885
  }

2886
  Literal* NewNumberLiteral(double number, int pos);
2887

2888 2889
  Literal* NewSmiLiteral(int number, int pos) {
    return new (zone_) Literal(number, pos);
2890 2891
  }

2892 2893
  Literal* NewBigIntLiteral(AstBigInt bigint, int pos) {
    return new (zone_) Literal(bigint, pos);
2894 2895
  }

2896
  Literal* NewBooleanLiteral(bool b, int pos) {
2897
    return new (zone_) Literal(b, pos);
2898 2899 2900
  }

  Literal* NewNullLiteral(int pos) {
2901
    return new (zone_) Literal(Literal::kNull, pos);
2902 2903 2904
  }

  Literal* NewUndefinedLiteral(int pos) {
2905
    return new (zone_) Literal(Literal::kUndefined, pos);
2906 2907
  }

2908
  Literal* NewTheHoleLiteral() {
2909
    return new (zone_) Literal(Literal::kTheHole, kNoSourcePosition);
2910 2911 2912
  }

  ObjectLiteral* NewObjectLiteral(
2913
      const ScopedPtrList<ObjectLiteral::Property>& properties,
2914
      uint32_t boilerplate_properties, int pos, bool has_rest_property) {
2915 2916
    return new (zone_) ObjectLiteral(zone_, properties, boilerplate_properties,
                                     pos, has_rest_property);
2917 2918
  }

2919 2920
  ObjectLiteral::Property* NewObjectLiteralProperty(
      Expression* key, Expression* value, ObjectLiteralProperty::Kind kind,
2921
      bool is_computed_name) {
2922
    return new (zone_)
2923
        ObjectLiteral::Property(key, value, kind, is_computed_name);
2924 2925
  }

arv's avatar
arv committed
2926
  ObjectLiteral::Property* NewObjectLiteralProperty(Expression* key,
arv@chromium.org's avatar
arv@chromium.org committed
2927
                                                    Expression* value,
arv's avatar
arv committed
2928
                                                    bool is_computed_name) {
2929
    return new (zone_) ObjectLiteral::Property(ast_value_factory_, key, value,
2930
                                               is_computed_name);
2931 2932
  }

2933
  RegExpLiteral* NewRegExpLiteral(const AstRawString* pattern, int flags,
2934 2935
                                  int pos) {
    return new (zone_) RegExpLiteral(pattern, flags, pos);
2936 2937
  }

2938 2939
  ArrayLiteral* NewArrayLiteral(const ScopedPtrList<Expression>& values,
                                int pos) {
2940
    return new (zone_) ArrayLiteral(zone_, values, -1, pos);
2941 2942
  }

2943
  ArrayLiteral* NewArrayLiteral(const ScopedPtrList<Expression>& values,
2944
                                int first_spread_index, int pos) {
2945
    return new (zone_) ArrayLiteral(zone_, values, first_spread_index, pos);
2946 2947
  }

2948
  VariableProxy* NewVariableProxy(Variable* var,
2949 2950
                                  int start_position = kNoSourcePosition) {
    return new (zone_) VariableProxy(var, start_position);
2951 2952
  }

2953
  VariableProxy* NewVariableProxy(const AstRawString* name,
2954
                                  VariableKind variable_kind,
2955
                                  int start_position = kNoSourcePosition) {
2956
    DCHECK_NOT_NULL(name);
2957
    return new (zone_) VariableProxy(name, variable_kind, start_position);
2958 2959 2960 2961
  }

  // Recreates the VariableProxy in this Zone.
  VariableProxy* CopyVariableProxy(VariableProxy* proxy) {
2962
    return new (zone_) VariableProxy(proxy);
2963 2964
  }

2965 2966 2967 2968
  Variable* CopyVariable(Variable* variable) {
    return new (zone_) Variable(variable);
  }

2969 2970 2971 2972 2973 2974 2975
  OptionalChain* NewOptionalChain(Expression* expression) {
    return new (zone_) OptionalChain(expression);
  }

  Property* NewProperty(Expression* obj, Expression* key, int pos,
                        bool optional_chain = false) {
    return new (zone_) Property(obj, key, pos, optional_chain);
2976 2977
  }

2978 2979
  Call* NewCall(Expression* expression,
                const ScopedPtrList<Expression>& arguments, int pos,
2980 2981 2982 2983
                Call::PossiblyEval possibly_eval = Call::NOT_EVAL,
                bool optional_chain = false) {
    return new (zone_)
        Call(zone_, expression, arguments, pos, possibly_eval, optional_chain);
2984 2985
  }

2986
  Call* NewTaggedTemplate(Expression* expression,
2987
                          const ScopedPtrList<Expression>& arguments, int pos) {
2988
    return new (zone_)
2989
        Call(zone_, expression, arguments, pos, Call::TaggedTemplateTag::kTrue);
2990 2991
  }

2992
  CallNew* NewCallNew(Expression* expression,
2993
                      const ScopedPtrList<Expression>& arguments, int pos) {
2994
    return new (zone_) CallNew(zone_, expression, arguments, pos);
2995 2996
  }

2997
  CallRuntime* NewCallRuntime(Runtime::FunctionId id,
2998 2999
                              const ScopedPtrList<Expression>& arguments,
                              int pos) {
3000 3001
    return new (zone_)
        CallRuntime(zone_, Runtime::FunctionForId(id), arguments, pos);
3002 3003 3004
  }

  CallRuntime* NewCallRuntime(const Runtime::Function* function,
3005 3006
                              const ScopedPtrList<Expression>& arguments,
                              int pos) {
3007
    return new (zone_) CallRuntime(zone_, function, arguments, pos);
3008 3009 3010
  }

  CallRuntime* NewCallRuntime(int context_index,
3011 3012
                              const ScopedPtrList<Expression>& arguments,
                              int pos) {
3013
    return new (zone_) CallRuntime(zone_, context_index, arguments, pos);
3014 3015 3016 3017 3018
  }

  UnaryOperation* NewUnaryOperation(Token::Value op,
                                    Expression* expression,
                                    int pos) {
3019
    return new (zone_) UnaryOperation(op, expression, pos);
3020 3021 3022 3023 3024 3025
  }

  BinaryOperation* NewBinaryOperation(Token::Value op,
                                      Expression* left,
                                      Expression* right,
                                      int pos) {
3026
    return new (zone_) BinaryOperation(op, left, right, pos);
3027 3028
  }

3029
  NaryOperation* NewNaryOperation(Token::Value op, Expression* first,
3030 3031
                                  size_t initial_subsequent_size) {
    return new (zone_) NaryOperation(zone_, op, first, initial_subsequent_size);
3032 3033
  }

3034 3035 3036 3037
  CountOperation* NewCountOperation(Token::Value op,
                                    bool is_prefix,
                                    Expression* expr,
                                    int pos) {
3038
    return new (zone_) CountOperation(op, is_prefix, expr, pos);
3039 3040 3041 3042 3043 3044
  }

  CompareOperation* NewCompareOperation(Token::Value op,
                                        Expression* left,
                                        Expression* right,
                                        int pos) {
3045
    return new (zone_) CompareOperation(op, left, right, pos);
3046 3047
  }

nikolaos's avatar
nikolaos committed
3048
  Spread* NewSpread(Expression* expression, int pos, int expr_pos) {
3049
    return new (zone_) Spread(expression, pos, expr_pos);
3050 3051
  }

3052 3053 3054
  Conditional* NewConditional(Expression* condition,
                              Expression* then_expression,
                              Expression* else_expression,
3055
                              int position) {
3056 3057
    return new (zone_)
        Conditional(condition, then_expression, else_expression, position);
3058 3059 3060 3061 3062 3063
  }

  Assignment* NewAssignment(Token::Value op,
                            Expression* target,
                            Expression* value,
                            int pos) {
3064
    DCHECK(Token::IsAssignmentOp(op));
3065 3066
    DCHECK_NOT_NULL(target);
    DCHECK_NOT_NULL(value);
3067 3068 3069 3070 3071

    if (op != Token::INIT && target->IsVariableProxy()) {
      target->AsVariableProxy()->set_is_assigned();
    }

3072 3073 3074 3075 3076 3077 3078 3079
    if (op == Token::ASSIGN || op == Token::INIT) {
      return new (zone_)
          Assignment(AstNode::kAssignment, op, target, value, pos);
    } else {
      return new (zone_) CompoundAssignment(
          op, target, value, pos,
          NewBinaryOperation(Token::BinaryOpForAssignment(op), target, value,
                             pos + 1));
3080
    }
3081 3082
  }

3083 3084
  Suspend* NewYield(Expression* expression, int pos,
                    Suspend::OnAbruptResume on_abrupt_resume) {
3085
    if (!expression) expression = NewUndefinedLiteral(pos);
3086
    return new (zone_) Yield(expression, pos, on_abrupt_resume);
3087 3088
  }

3089 3090
  YieldStar* NewYieldStar(Expression* expression, int pos) {
    return new (zone_) YieldStar(expression, pos);
3091 3092
  }

3093
  Await* NewAwait(Expression* expression, int pos) {
3094
    if (!expression) expression = NewUndefinedLiteral(pos);
3095
    return new (zone_) Await(expression, pos);
3096 3097
  }

3098 3099
  Throw* NewThrow(Expression* exception, int pos) {
    return new (zone_) Throw(exception, pos);
3100 3101 3102
  }

  FunctionLiteral* NewFunctionLiteral(
3103
      const AstRawString* name, DeclarationScope* scope,
3104
      const ScopedPtrList<Statement>& body, int expected_property_count,
3105
      int parameter_count, int function_length,
3106
      FunctionLiteral::ParameterFlag has_duplicate_parameters,
3107
      FunctionSyntaxKind function_syntax_kind,
3108
      FunctionLiteral::EagerCompileHint eager_compile_hint, int position,
3109
      bool has_braces, int function_literal_id,
3110
      ProducedPreparseData* produced_preparse_data = nullptr) {
3111
    return new (zone_) FunctionLiteral(
3112 3113
        zone_, name ? ast_value_factory_->NewConsString(name) : nullptr,
        ast_value_factory_, scope, body, expected_property_count,
3114
        parameter_count, function_length, function_syntax_kind,
3115
        has_duplicate_parameters, eager_compile_hint, position, has_braces,
3116
        function_literal_id, produced_preparse_data);
3117 3118 3119 3120 3121
  }

  // Creates a FunctionLiteral representing a top-level script, the
  // result of an eval (top-level or otherwise), or the result of calling
  // the Function constructor.
3122 3123 3124
  FunctionLiteral* NewScriptOrEvalFunctionLiteral(
      DeclarationScope* scope, const ScopedPtrList<Statement>& body,
      int expected_property_count, int parameter_count) {
3125
    return new (zone_) FunctionLiteral(
3126 3127
        zone_, ast_value_factory_->empty_cons_string(), ast_value_factory_,
        scope, body, expected_property_count, parameter_count, parameter_count,
3128
        FunctionSyntaxKind::kAnonymousExpression,
3129
        FunctionLiteral::kNoDuplicateParameters,
3130
        FunctionLiteral::kShouldLazyCompile, 0, /* has_braces */ false,
3131
        kFunctionLiteralIdTopLevel);
3132 3133
  }

3134 3135
  ClassLiteral::Property* NewClassLiteralProperty(
      Expression* key, Expression* value, ClassLiteralProperty::Kind kind,
3136 3137 3138
      bool is_static, bool is_computed_name, bool is_private) {
    return new (zone_) ClassLiteral::Property(key, value, kind, is_static,
                                              is_computed_name, is_private);
3139 3140
  }

3141
  ClassLiteral* NewClassLiteral(
3142
      ClassScope* scope, Expression* extends, FunctionLiteral* constructor,
3143 3144
      ZonePtrList<ClassLiteral::Property>* public_members,
      ZonePtrList<ClassLiteral::Property>* private_members,
3145
      FunctionLiteral* static_fields_initializer,
3146 3147
      FunctionLiteral* instance_members_initializer_function,
      int start_position, int end_position, bool has_name_static_property,
3148 3149
      bool has_static_computed_names, bool is_anonymous,
      bool has_private_methods) {
3150
    return new (zone_) ClassLiteral(
3151 3152 3153 3154
        scope, extends, constructor, public_members, private_members,
        static_fields_initializer, instance_members_initializer_function,
        start_position, end_position, has_name_static_property,
        has_static_computed_names, is_anonymous, has_private_methods);
arv@chromium.org's avatar
arv@chromium.org committed
3155 3156
  }

3157 3158 3159
  NativeFunctionLiteral* NewNativeFunctionLiteral(const AstRawString* name,
                                                  v8::Extension* extension,
                                                  int pos) {
3160
    return new (zone_) NativeFunctionLiteral(name, extension, pos);
3161 3162
  }

3163
  SuperPropertyReference* NewSuperPropertyReference(Expression* home_object,
3164
                                                    int pos) {
3165
    return new (zone_) SuperPropertyReference(home_object, pos);
3166 3167
  }

3168
  SuperCallReference* NewSuperCallReference(VariableProxy* new_target_var,
3169 3170
                                            VariableProxy* this_function_var,
                                            int pos) {
3171
    return new (zone_)
3172
        SuperCallReference(new_target_var, this_function_var, pos);
3173 3174
  }

3175
  EmptyParentheses* NewEmptyParentheses(int pos) {
3176
    return new (zone_) EmptyParentheses(pos);
3177 3178
  }

3179
  GetTemplateObject* NewGetTemplateObject(
3180 3181
      const ZonePtrList<const AstRawString>* cooked_strings,
      const ZonePtrList<const AstRawString>* raw_strings, int pos) {
3182
    return new (zone_) GetTemplateObject(cooked_strings, raw_strings, pos);
3183 3184
  }

3185
  TemplateLiteral* NewTemplateLiteral(
3186 3187
      const ZonePtrList<const AstRawString>* string_parts,
      const ZonePtrList<Expression>* substitutions, int pos) {
3188 3189 3190
    return new (zone_) TemplateLiteral(string_parts, substitutions, pos);
  }

3191 3192 3193 3194
  ImportCallExpression* NewImportCallExpression(Expression* args, int pos) {
    return new (zone_) ImportCallExpression(args, pos);
  }

3195
  InitializeClassMembersStatement* NewInitializeClassMembersStatement(
3196
      ZonePtrList<ClassLiteral::Property>* args, int pos) {
3197
    return new (zone_) InitializeClassMembersStatement(args, pos);
3198 3199
  }

3200
  Zone* zone() const { return zone_; }
3201

3202
 private:
3203 3204 3205 3206
  // This zone may be deallocated upon returning from parsing a function body
  // which we can guarantee is not going to be compiled or have its AST
  // inspected.
  // See ParseFunctionLiteral in parser.cc for preconditions.
3207
  Zone* zone_;
3208
  AstValueFactory* ast_value_factory_;
3209
  class EmptyStatement* empty_statement_;
3210
  class ThisExpression* this_expression_;
3211
  class FailureExpression* failure_expression_;
3212 3213 3214
};


3215 3216 3217
// Type testing & conversion functions overridden by concrete subclasses.
// Inline functions for AstNode.

3218
#define DECLARE_NODE_FUNCTIONS(type)                                         \
3219
  bool AstNode::Is##type() const { return node_type() == AstNode::k##type; } \
3220
  type* AstNode::As##type() {                                                \
3221 3222
    return node_type() == AstNode::k##type ? reinterpret_cast<type*>(this)   \
                                           : nullptr;                        \
3223 3224
  }                                                                          \
  const type* AstNode::As##type() const {                                    \
3225 3226 3227
    return node_type() == AstNode::k##type                                   \
               ? reinterpret_cast<const type*>(this)                         \
               : nullptr;                                                    \
3228 3229
  }
AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
3230
FAILURE_NODE_LIST(DECLARE_NODE_FUNCTIONS)
3231 3232
#undef DECLARE_NODE_FUNCTIONS

3233 3234
}  // namespace internal
}  // namespace v8
3235

3236
#endif  // V8_AST_AST_H_