ast.h 111 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/execution/isolate.h"
18
#include "src/heap/factory.h"
19
#include "src/objects/elements-kind.h"
20
#include "src/objects/function-syntax-kind.h"
21
#include "src/objects/literal-objects.h"
22
#include "src/objects/smi.h"
23
#include "src/parsing/token.h"
24
#include "src/runtime/runtime.h"
25

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

// 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
42 43
#define DECLARATION_NODE_LIST(V) \
  V(VariableDeclaration)         \
44
  V(FunctionDeclaration)
45

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

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

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

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

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

113 114
#define FAILURE_NODE_LIST(V) V(FailureExpression)

115
#define AST_NODE_LIST(V)                        \
116
  DECLARATION_NODE_LIST(V)                      \
117
  STATEMENT_NODE_LIST(V)                        \
118
  EXPRESSION_NODE_LIST(V)
119

120
// Forward declarations
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 298 299 300 301 302 303 304 305 306 307 308 309 310 311
// 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
// statement.  The BreakableStatement AST node carries a list of labels, any of
// which can be used as an argument to the break statement in order to target
// it.
//
// Since we don't want to attach a list of labels to all kinds of statements, we
// 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.
//
// This optimization makes it harder to detect invalid continue labels, see the
// need for own_labels in IterationStatement.
//
312
class BreakableStatement : public Statement {
313
 public:
314
  enum BreakableType {
315 316 317 318
    TARGET_FOR_ANONYMOUS,
    TARGET_FOR_NAMED_ONLY
  };

319 320 321 322 323 324 325
  // A list of all labels declared on the path up to the previous
  // BreakableStatement (if any).
  //
  // Example: "l1: for (;;) l2: l3: { l4: if (b) l5: { s } }"
  // labels() of the ForStatement will be l1.
  // labels() of the Block { l4: ... } will be l2, l3.
  // labels() of the Block { s } will be l4, l5.
326
  ZonePtrList<const AstRawString>* labels() const;
327 328

  // Testers.
329
  bool is_target_for_anonymous() const {
330
    return BreakableTypeField::decode(bit_field_) == TARGET_FOR_ANONYMOUS;
331
  }
332

333
 private:
334
  using BreakableTypeField = Statement::NextBitField<BreakableType, 1>;
335

336
 protected:
337 338
  BreakableStatement(BreakableType breakable_type, int position, NodeType type)
      : Statement(position, type) {
339
    bit_field_ |= BreakableTypeField::encode(breakable_type);
340 341
  }

342 343
  template <class T, int size>
  using NextBitField = BreakableTypeField::Next<T, size>;
344 345
};

346
class Block : public BreakableStatement {
347
 public:
348
  ZonePtrList<Statement>* statements() { return &statements_; }
349 350 351
  bool ignore_completion_value() const {
    return IgnoreCompletionField::decode(bit_field_);
  }
352

353
  inline ZonePtrList<const AstRawString>* labels() const;
354

355 356
  Scope* scope() const { return scope_; }
  void set_scope(Scope* scope) { scope_ = scope; }
357

358 359 360 361 362 363
  void InitializeStatements(const ScopedPtrList<Statement>& statements,
                            Zone* zone) {
    DCHECK_EQ(0, statements_.length());
    statements.CopyTo(&statements_, zone);
  }

364 365 366
 private:
  friend class AstNodeFactory;

367
  ZonePtrList<Statement> statements_;
368 369
  Scope* scope_;

370 371
  using IgnoreCompletionField = BreakableStatement::NextBitField<bool, 1>;
  using IsLabeledField = IgnoreCompletionField::Next<bool, 1>;
372 373

 protected:
374
  Block(Zone* zone, ZonePtrList<const AstRawString>* labels, int capacity,
375 376
        bool ignore_completion_value)
      : BreakableStatement(TARGET_FOR_NAMED_ONLY, kNoSourcePosition, kBlock),
377
        statements_(capacity, zone),
378
        scope_(nullptr) {
379 380
    bit_field_ |= IgnoreCompletionField::encode(ignore_completion_value) |
                  IsLabeledField::encode(labels != nullptr);
381
  }
382 383 384

  Block(ZonePtrList<const AstRawString>* labels, bool ignore_completion_value)
      : Block(nullptr, labels, 0, ignore_completion_value) {}
385
};
386

387 388 389 390
class LabeledBlock final : public Block {
 private:
  friend class AstNodeFactory;
  friend class Block;
391

392 393
  LabeledBlock(Zone* zone, ZonePtrList<const AstRawString>* labels,
               int capacity, bool ignore_completion_value)
394
      : Block(zone, labels, capacity, ignore_completion_value),
395 396 397 398 399
        labels_(labels) {
    DCHECK_NOT_NULL(labels);
    DCHECK_GT(labels->length(), 0);
  }

400 401 402 403
  LabeledBlock(ZonePtrList<const AstRawString>* labels,
               bool ignore_completion_value)
      : LabeledBlock(nullptr, labels, 0, ignore_completion_value) {}

404
  ZonePtrList<const AstRawString>* labels_;
405 406
};

407
inline ZonePtrList<const AstRawString>* Block::labels() const {
408 409 410 411 412
  if (IsLabeledField::decode(bit_field_)) {
    return static_cast<const LabeledBlock*>(this)->labels_;
  }
  return nullptr;
}
413

414 415 416 417 418
class DoExpression final : public Expression {
 public:
  Block* block() { return block_; }
  VariableProxy* result() { return result_; }

419 420 421
 private:
  friend class AstNodeFactory;

422
  DoExpression(Block* block, VariableProxy* result, int pos)
423
      : Expression(pos, kDoExpression), block_(block), result_(result) {
424 425 426 427 428 429 430 431 432
    DCHECK_NOT_NULL(block_);
    DCHECK_NOT_NULL(result_);
  }

  Block* block_;
  VariableProxy* result_;
};


433
class Declaration : public AstNode {
434
 public:
435
  using List = base::ThreadedList<Declaration>;
436

437 438
  Variable* var() const { return var_; }
  void set_var(Variable* var) { var_ = var; }
439

440
 protected:
441
  Declaration(int pos, NodeType type) : AstNode(pos, type), next_(nullptr) {}
442 443

 private:
444
  Variable* var_;
445 446 447 448
  // Declarations list threaded through the declarations.
  Declaration** next() { return &next_; }
  Declaration* next_;
  friend List;
449
  friend base::ThreadedListTraits<Declaration>;
450 451
};

452 453 454
class VariableDeclaration : public Declaration {
 public:
  inline NestedVariableDeclaration* AsNested();
455

456 457 458
 private:
  friend class AstNodeFactory;

459
  using IsNestedField = Declaration::NextBitField<bool, 1>;
460 461

 protected:
462 463
  explicit VariableDeclaration(int pos, bool is_nested = false)
      : Declaration(pos, kVariableDeclaration) {
464 465 466
    bit_field_ = IsNestedField::update(bit_field_, is_nested);
  }

467 468
  template <class T, int size>
  using NextBitField = IsNestedField::Next<T, size>;
469 470
};

471 472 473 474 475 476 477 478 479 480
// 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;

481 482
  NestedVariableDeclaration(Scope* scope, int pos)
      : VariableDeclaration(pos, true), scope_(scope) {}
483 484 485 486 487 488 489 490 491 492

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

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

494
class FunctionDeclaration final : public Declaration {
495 496
 public:
  FunctionLiteral* fun() const { return fun_; }
497

498 499 500
 private:
  friend class AstNodeFactory;

501 502
  FunctionDeclaration(FunctionLiteral* fun, int pos)
      : Declaration(pos, kFunctionDeclaration), fun_(fun) {}
503 504 505 506 507

  FunctionLiteral* fun_;
};


508
class IterationStatement : public BreakableStatement {
509 510
 public:
  Statement* body() const { return body_; }
511
  void set_body(Statement* s) { body_ = s; }
512

513
  ZonePtrList<const AstRawString>* labels() const { return labels_; }
514

515 516 517 518 519 520 521 522 523 524
  // A list of all labels that the iteration statement is directly prefixed
  // with, i.e.  all the labels that a continue statement in the body can use to
  // continue this iteration statement. This is always a subset of {labels}.
  //
  // Example: "l1: { l2: if (b) l3: l4: for (;;) s }"
  // labels() of the Block will be l1.
  // labels() of the ForStatement will be l2, l3, l4.
  // own_labels() of the ForStatement will be l3, l4.
  ZonePtrList<const AstRawString>* own_labels() const { return own_labels_; }

525
 protected:
526 527
  IterationStatement(ZonePtrList<const AstRawString>* labels,
                     ZonePtrList<const AstRawString>* own_labels, int pos,
528
                     NodeType type)
529 530
      : BreakableStatement(TARGET_FOR_ANONYMOUS, pos, type),
        labels_(labels),
531
        own_labels_(own_labels),
532
        body_(nullptr) {}
533
  void Initialize(Statement* body) { body_ = body; }
534

535
 private:
536
  ZonePtrList<const AstRawString>* labels_;
537
  ZonePtrList<const AstRawString>* own_labels_;
538 539 540 541
  Statement* body_;
};


542
class DoWhileStatement final : public IterationStatement {
543
 public:
544 545
  void Initialize(Expression* cond, Statement* body) {
    IterationStatement::Initialize(body);
546 547
    cond_ = cond;
  }
548

549 550
  Expression* cond() const { return cond_; }

551 552 553
 private:
  friend class AstNodeFactory;

554 555 556 557
  DoWhileStatement(ZonePtrList<const AstRawString>* labels,
                   ZonePtrList<const AstRawString>* own_labels, int pos)
      : IterationStatement(labels, own_labels, pos, kDoWhileStatement),
        cond_(nullptr) {}
558

559 560 561 562
  Expression* cond_;
};


563
class WhileStatement final : public IterationStatement {
564
 public:
565 566
  void Initialize(Expression* cond, Statement* body) {
    IterationStatement::Initialize(body);
567 568 569 570 571
    cond_ = cond;
  }

  Expression* cond() const { return cond_; }

572 573 574
 private:
  friend class AstNodeFactory;

575 576 577 578
  WhileStatement(ZonePtrList<const AstRawString>* labels,
                 ZonePtrList<const AstRawString>* own_labels, int pos)
      : IterationStatement(labels, own_labels, pos, kWhileStatement),
        cond_(nullptr) {}
579

580 581 582 583
  Expression* cond_;
};


584
class ForStatement final : public IterationStatement {
585
 public:
586
  void Initialize(Statement* init, Expression* cond, Statement* next,
587 588
                  Statement* body) {
    IterationStatement::Initialize(body);
589 590 591 592 593
    init_ = init;
    cond_ = cond;
    next_ = next;
  }

594 595 596
  Statement* init() const { return init_; }
  Expression* cond() const { return cond_; }
  Statement* next() const { return next_; }
597

598 599 600
 private:
  friend class AstNodeFactory;

601 602 603
  ForStatement(ZonePtrList<const AstRawString>* labels,
               ZonePtrList<const AstRawString>* own_labels, int pos)
      : IterationStatement(labels, own_labels, pos, kForStatement),
604 605 606
        init_(nullptr),
        cond_(nullptr),
        next_(nullptr) {}
607

608 609 610 611 612
  Statement* init_;
  Expression* cond_;
  Statement* next_;
};

613
// Shared class for for-in and for-of statements.
614
class ForEachStatement : public IterationStatement {
615
 public:
616 617 618 619
  enum VisitMode {
    ENUMERATE,   // for (each in subject) body;
    ITERATE      // for (each of subject) body;
  };
620

621
  using IterationStatement::Initialize;
622

623 624 625 626
  static const char* VisitModeString(VisitMode mode) {
    return mode == ITERATE ? "for-of" : "for-in";
  }

627
  void Initialize(Expression* each, Expression* subject, Statement* body) {
628
    IterationStatement::Initialize(body);
629 630 631 632 633 634 635
    each_ = each;
    subject_ = subject;
  }

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

636
 protected:
637 638
  friend class AstNodeFactory;

639 640 641 642
  ForEachStatement(ZonePtrList<const AstRawString>* labels,
                   ZonePtrList<const AstRawString>* own_labels, int pos,
                   NodeType type)
      : IterationStatement(labels, own_labels, pos, type),
643
        each_(nullptr),
644
        subject_(nullptr) {}
645

646 647
  Expression* each_;
  Expression* subject_;
648
};
649

650 651 652 653 654 655 656 657
class ForInStatement final : public ForEachStatement {
 private:
  friend class AstNodeFactory;

  ForInStatement(ZonePtrList<const AstRawString>* labels,
                 ZonePtrList<const AstRawString>* own_labels, int pos)
      : ForEachStatement(labels, own_labels, pos, kForInStatement) {}
};
658

659
enum class IteratorType { kNormal, kAsync };
660
class ForOfStatement final : public ForEachStatement {
661
 public:
662
  IteratorType type() const { return type_; }
663

664 665 666
 private:
  friend class AstNodeFactory;

667
  ForOfStatement(ZonePtrList<const AstRawString>* labels,
668 669
                 ZonePtrList<const AstRawString>* own_labels, int pos,
                 IteratorType type)
670
      : ForEachStatement(labels, own_labels, pos, kForOfStatement),
671
        type_(type) {}
672

673
  IteratorType type_;
674 675
};

676
class ExpressionStatement final : public Statement {
677 678
 public:
  void set_expression(Expression* e) { expression_ = e; }
679
  Expression* expression() const { return expression_; }
680

681 682 683
 private:
  friend class AstNodeFactory;

684 685
  ExpressionStatement(Expression* expression, int pos)
      : Statement(pos, kExpressionStatement), expression_(expression) {}
686

687 688 689 690
  Expression* expression_;
};


691
class JumpStatement : public Statement {
692
 protected:
693
  JumpStatement(int pos, NodeType type) : Statement(pos, type) {}
694 695 696
};


697
class ContinueStatement final : public JumpStatement {
698
 public:
699
  IterationStatement* target() const { return target_; }
700

701 702 703
 private:
  friend class AstNodeFactory;

704 705
  ContinueStatement(IterationStatement* target, int pos)
      : JumpStatement(pos, kContinueStatement), target_(target) {}
706 707 708 709 710

  IterationStatement* target_;
};


711
class BreakStatement final : public JumpStatement {
712
 public:
713
  BreakableStatement* target() const { return target_; }
714

715 716 717
 private:
  friend class AstNodeFactory;

718 719
  BreakStatement(BreakableStatement* target, int pos)
      : JumpStatement(pos, kBreakStatement), target_(target) {}
720 721 722 723 724

  BreakableStatement* target_;
};


725
class ReturnStatement final : public JumpStatement {
726
 public:
727
  enum Type { kNormal, kAsyncReturn, kSyntheticAsyncReturn };
728
  Expression* expression() const { return expression_; }
729

730
  Type type() const { return TypeField::decode(bit_field_); }
731 732 733 734
  bool is_async_return() const { return type() != kNormal; }
  bool is_synthetic_async_return() const {
    return type() == kSyntheticAsyncReturn;
  }
735

736 737
  int end_position() const { return end_position_; }

738 739 740
 private:
  friend class AstNodeFactory;

741 742 743 744
  ReturnStatement(Expression* expression, Type type, int pos, int end_position)
      : JumpStatement(pos, kReturnStatement),
        expression_(expression),
        end_position_(end_position) {
745 746
    bit_field_ |= TypeField::encode(type);
  }
747 748

  Expression* expression_;
749
  int end_position_;
750

751
  using TypeField = JumpStatement::NextBitField<Type, 2>;
752 753 754
};


755
class WithStatement final : public Statement {
756
 public:
757
  Scope* scope() { return scope_; }
758
  Expression* expression() const { return expression_; }
759
  Statement* statement() const { return statement_; }
760
  void set_statement(Statement* s) { statement_ = s; }
761

762 763 764
 private:
  friend class AstNodeFactory;

765 766 767
  WithStatement(Scope* scope, Expression* expression, Statement* statement,
                int pos)
      : Statement(pos, kWithStatement),
768
        scope_(scope),
769
        expression_(expression),
770
        statement_(statement) {}
771

772
  Scope* scope_;
773
  Expression* expression_;
774
  Statement* statement_;
775 776
};

777
class CaseClause final : public ZoneObject {
778
 public:
779
  bool is_default() const { return label_ == nullptr; }
780
  Expression* label() const {
781
    DCHECK(!is_default());
782 783
    return label_;
  }
784
  ZonePtrList<Statement>* statements() { return &statements_; }
785 786

 private:
787 788
  friend class AstNodeFactory;

789 790
  CaseClause(Zone* zone, Expression* label,
             const ScopedPtrList<Statement>& statements);
791

792
  Expression* label_;
793
  ZonePtrList<Statement> statements_;
794 795 796
};


797
class SwitchStatement final : public BreakableStatement {
798
 public:
799
  ZonePtrList<const AstRawString>* labels() const { return labels_; }
800

801
  Expression* tag() const { return tag_; }
802 803
  void set_tag(Expression* t) { tag_ = t; }

804
  ZonePtrList<CaseClause>* cases() { return &cases_; }
805

806 807 808
 private:
  friend class AstNodeFactory;

809
  SwitchStatement(Zone* zone, ZonePtrList<const AstRawString>* labels,
810
                  Expression* tag, int pos)
811 812
      : BreakableStatement(TARGET_FOR_ANONYMOUS, pos, kSwitchStatement),
        labels_(labels),
813 814
        tag_(tag),
        cases_(4, zone) {}
815

816
  ZonePtrList<const AstRawString>* labels_;
817
  Expression* tag_;
818
  ZonePtrList<CaseClause> cases_;
819 820 821 822 823 824 825 826
};


// 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.
827
class IfStatement final : public Statement {
828
 public:
829 830
  bool HasThenStatement() const { return !then_statement_->IsEmptyStatement(); }
  bool HasElseStatement() const { return !else_statement_->IsEmptyStatement(); }
831 832 833 834 835

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

836 837 838
  void set_then_statement(Statement* s) { then_statement_ = s; }
  void set_else_statement(Statement* s) { else_statement_ = s; }

839 840 841
 private:
  friend class AstNodeFactory;

842
  IfStatement(Expression* condition, Statement* then_statement,
843
              Statement* else_statement, int pos)
844
      : Statement(pos, kIfStatement),
845
        condition_(condition),
846
        then_statement_(then_statement),
847
        else_statement_(else_statement) {}
848

849 850 851 852 853 854
  Expression* condition_;
  Statement* then_statement_;
  Statement* else_statement_;
};


855
class TryStatement : public Statement {
856 857
 public:
  Block* try_block() const { return try_block_; }
858
  void set_try_block(Block* b) { try_block_ = b; }
859 860

 protected:
861
  TryStatement(Block* try_block, int pos, NodeType type)
862
      : Statement(pos, type), try_block_(try_block) {}
863

864
 private:
865
  Block* try_block_;
866 867 868
};


869
class TryCatchStatement final : public TryStatement {
870
 public:
871 872
  Scope* scope() { return scope_; }
  Block* catch_block() const { return catch_block_; }
873
  void set_catch_block(Block* b) { catch_block_ = b; }
874

875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913
  // 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.
914
  // (When the catch block doesn't rethrow but is guaranteed to perform an
915 916
  // ordinary throw, not clearing the old message is safe but not very
  // useful.)
917 918 919 920
  //
  // 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.
921 922
  inline bool ShouldClearPendingException(
      HandlerTable::CatchPrediction outer_catch_prediction) const {
923 924 925 926 927
    if (catch_prediction_ == HandlerTable::UNCAUGHT_ASYNC_AWAIT) {
      DCHECK_EQ(outer_catch_prediction, HandlerTable::UNCAUGHT);
      return false;
    }

928 929
    return catch_prediction_ != HandlerTable::UNCAUGHT ||
           outer_catch_prediction != HandlerTable::UNCAUGHT;
930
  }
931

932 933 934 935
  bool is_try_catch_for_async() {
    return catch_prediction_ == HandlerTable::ASYNC_AWAIT;
  }

936 937 938
 private:
  friend class AstNodeFactory;

939
  TryCatchStatement(Block* try_block, Scope* scope, Block* catch_block,
940
                    HandlerTable::CatchPrediction catch_prediction, int pos)
941
      : TryStatement(try_block, pos, kTryCatchStatement),
942
        scope_(scope),
943
        catch_block_(catch_block),
944
        catch_prediction_(catch_prediction) {}
945

946
  Scope* scope_;
947
  Block* catch_block_;
948
  HandlerTable::CatchPrediction catch_prediction_;
949 950 951
};


952
class TryFinallyStatement final : public TryStatement {
953 954
 public:
  Block* finally_block() const { return finally_block_; }
955
  void set_finally_block(Block* b) { finally_block_ = b; }
956

957 958 959
 private:
  friend class AstNodeFactory;

960
  TryFinallyStatement(Block* try_block, Block* finally_block, int pos)
961
      : TryStatement(try_block, pos, kTryFinallyStatement),
962
        finally_block_(finally_block) {}
963 964 965 966 967

  Block* finally_block_;
};


968
class DebuggerStatement final : public Statement {
969 970 971
 private:
  friend class AstNodeFactory;

972
  explicit DebuggerStatement(int pos) : Statement(pos, kDebuggerStatement) {}
973 974 975
};


976
class EmptyStatement final : public Statement {
977 978
 private:
  friend class AstNodeFactory;
979
  EmptyStatement() : Statement(kNoSourcePosition, kEmptyStatement) {}
980 981 982
};


983 984 985 986 987 988 989 990
// 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; }
991 992 993 994 995
  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_; }
996 997

 private:
998 999
  friend class AstNodeFactory;

1000
  using TokenField = Statement::NextBitField<Token::Value, 8>;
1001 1002 1003 1004 1005 1006 1007 1008 1009

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

1011
  Variable* var_;
1012
  Statement* statement_;
1013
  SloppyBlockFunctionStatement* next_;
1014 1015 1016
};


1017
class Literal final : public Expression {
1018
 public:
1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032
  enum Type {
    kSmi,
    kHeapNumber,
    kBigInt,
    kString,
    kSymbol,
    kBoolean,
    kUndefined,
    kNull,
    kTheHole,
  };

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

1033
  // Returns true if literal represents a property name (i.e. cannot be parsed
1034
  // as array indices).
1035
  bool IsPropertyName() const;
1036 1037 1038 1039 1040 1041 1042 1043

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

1044
  const AstRawString* AsRawPropertyName() {
1045
    DCHECK(IsPropertyName());
1046
    return string_;
1047 1048
  }

1049
  Smi AsSmiLiteral() const {
1050 1051
    DCHECK_EQ(kSmi, type());
    return Smi::FromInt(smi_);
1052 1053
  }

1054
  // Returns true if literal represents a Number.
1055
  bool IsNumber() const { return type() == kHeapNumber || type() == kSmi; }
1056 1057
  double AsNumber() const {
    DCHECK(IsNumber());
1058 1059 1060 1061 1062 1063 1064 1065
    switch (type()) {
      case kSmi:
        return smi_;
      case kHeapNumber:
        return number_;
      default:
        UNREACHABLE();
    }
1066 1067
  }

1068
  AstBigInt AsBigInt() const {
1069
    DCHECK_EQ(type(), kBigInt);
1070 1071 1072 1073
    return bigint_;
  }

  bool IsString() const { return type() == kString; }
1074
  const AstRawString* AsRawString() {
1075
    DCHECK_EQ(type(), kString);
1076 1077 1078 1079
    return string_;
  }

  AstSymbol AsSymbol() {
1080
    DCHECK_EQ(type(), kSymbol);
1081
    return symbol_;
1082 1083
  }

1084 1085
  V8_EXPORT_PRIVATE bool ToBooleanIsTrue() const;
  bool ToBooleanIsFalse() const { return !ToBooleanIsTrue(); }
1086 1087

  bool ToUint32(uint32_t* value) const;
1088

1089 1090
  // Returns an appropriate Object representing this Literal, allocating
  // a heap object if needed.
1091 1092
  template <typename Isolate>
  HandleFor<Isolate, Object> BuildValue(Isolate* isolate) const;
1093

1094 1095
  // Support for using Literal as a HashMap key. NOTE: Currently, this works
  // only for string and number literals!
1096 1097
  uint32_t Hash();
  static bool Match(void* literal1, void* literal2);
1098

1099 1100 1101
 private:
  friend class AstNodeFactory;

1102
  using TypeField = Expression::NextBitField<Type, 4>;
1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126

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

1128 1129 1130 1131 1132
  Literal(bool boolean, int position)
      : Expression(position, kLiteral), boolean_(boolean) {
    bit_field_ = TypeField::update(bit_field_, kBoolean);
  }

1133
  Literal(Type type, int position) : Expression(position, kLiteral) {
1134
    DCHECK(type == kNull || type == kUndefined || type == kTheHole);
1135 1136 1137 1138 1139 1140 1141 1142 1143
    bit_field_ = TypeField::update(bit_field_, type);
  }

  union {
    const AstRawString* string_;
    int smi_;
    double number_;
    AstSymbol symbol_;
    AstBigInt bigint_;
1144
    bool boolean_;
1145
  };
1146 1147
};

1148
// Base class for literals that need space in the type feedback vector.
1149
class MaterializedLiteral : public Expression {
1150
 public:
1151 1152 1153 1154
  // A Materializedliteral is simple if the values consist of only
  // constants and simple object and array literals.
  bool IsSimple() const;

1155
 protected:
1156
  MaterializedLiteral(int pos, NodeType type) : Expression(pos, type) {}
1157

1158
  friend class CompileTimeValue;
1159 1160
  friend class ArrayLiteral;
  friend class ObjectLiteral;
1161

1162 1163
  // Populate the depth field and any flags the literal has, returns the depth.
  int InitDepthAndFlags();
1164

1165
  bool NeedsInitialAllocationSite();
1166

1167
  // Populate the constant properties/elements fixed array.
1168
  template <typename Isolate>
1169
  void BuildConstants(Isolate* isolate);
1170 1171

  // If the expression is a literal, return the literal value;
1172 1173
  // if the expression is a materialized literal and is_simple
  // then return an Array or Object Boilerplate Description
1174 1175
  // Otherwise, return undefined literal as the placeholder
  // in the object literal boilerplate.
1176 1177 1178
  template <typename Isolate>
  HandleFor<Isolate, Object> GetBoilerplateValue(Expression* expression,
                                                 Isolate* isolate);
1179 1180 1181 1182 1183
};

// Node for capturing a regexp literal.
class RegExpLiteral final : public MaterializedLiteral {
 public:
1184
  HandleOrOffThreadHandle<String> pattern() const { return pattern_->string(); }
1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233
  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_); }

1234 1235 1236 1237
  ElementsKind boilerplate_descriptor_kind() const {
    return BoilerplateDescriptorKindField::decode(bit_field_);
  }

1238 1239
 private:
  int depth_ : 31;
1240
  using NeedsInitialAllocationSiteField =
1241 1242
      MaterializedLiteral::NextBitField<bool, 1>;
  using IsSimpleField = NeedsInitialAllocationSiteField::Next<bool, 1>;
1243 1244
  using BoilerplateDescriptorKindField =
      IsSimpleField::Next<ElementsKind, kFastElementsKindBits>;
1245 1246 1247 1248 1249

 protected:
  friend class AstNodeFactory;
  AggregateLiteral(int pos, NodeType type)
      : MaterializedLiteral(pos, type), depth_(0) {
1250 1251 1252 1253
    bit_field_ |=
        NeedsInitialAllocationSiteField::encode(false) |
        IsSimpleField::encode(false) |
        BoilerplateDescriptorKindField::encode(FIRST_FAST_ELEMENTS_KIND);
1254 1255 1256 1257 1258 1259
  }

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

1260 1261 1262 1263 1264
  void set_boilerplate_descriptor_kind(ElementsKind kind) {
    DCHECK(IsFastElementsKind(kind));
    bit_field_ = BoilerplateDescriptorKindField::update(bit_field_, kind);
  }

1265 1266 1267 1268 1269 1270 1271 1272
  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);
  }
1273

1274
  template <class T, int size>
1275
  using NextBitField = BoilerplateDescriptorKindField::Next<T, size>;
1276 1277
};

1278 1279 1280
// Common supertype for ObjectLiteralProperty and ClassLiteralProperty
class LiteralProperty : public ZoneObject {
 public:
1281
  Expression* key() const { return key_and_is_computed_name_.GetPointer(); }
1282 1283
  Expression* value() const { return value_; }

1284 1285 1286
  bool is_computed_name() const {
    return key_and_is_computed_name_.GetPayload();
  }
1287 1288 1289 1290
  bool NeedsSetFunctionName() const;

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

1293
  PointerWithPayload<Expression, bool, 1> key_and_is_computed_name_;
1294 1295
  Expression* value_;
};
1296

1297 1298 1299
// Property is used for passing information
// about an object literal's properties from the parser
// to the code generator.
1300
class ObjectLiteralProperty final : public LiteralProperty {
1301
 public:
1302
  enum Kind : uint8_t {
1303 1304 1305
    CONSTANT,              // Property with constant value (compile time).
    COMPUTED,              // Property with computed value (execution time).
    MATERIALIZED_LITERAL,  // Property value is a materialized literal.
1306
    GETTER,
1307 1308 1309
    SETTER,     // Property is an accessor function.
    PROTOTYPE,  // Property is __proto__.
    SPREAD
1310 1311
  };

1312
  Kind kind() const { return kind_; }
1313

1314
  bool IsCompileTimeValue() const;
1315 1316

  void set_emit_store(bool emit_store);
1317
  bool emit_store() const;
1318

1319 1320 1321 1322 1323
  bool IsNullPrototype() const {
    return IsPrototype() && value()->IsNullLiteral();
  }
  bool IsPrototype() const { return kind() == PROTOTYPE; }

1324
 private:
1325
  friend class AstNodeFactory;
1326

1327
  ObjectLiteralProperty(Expression* key, Expression* value, Kind kind,
arv's avatar
arv committed
1328
                        bool is_computed_name);
1329 1330
  ObjectLiteralProperty(AstValueFactory* ast_value_factory, Expression* key,
                        Expression* value, bool is_computed_name);
1331 1332 1333 1334 1335

  Kind kind_;
  bool emit_store_;
};

1336 1337
// An object literal has a boilerplate object that is used
// for minimizing the work when constructing it at runtime.
1338
class ObjectLiteral final : public AggregateLiteral {
1339
 public:
1340
  using Property = ObjectLiteralProperty;
1341

1342 1343 1344
  HandleOrOffThreadHandle<ObjectBoilerplateDescription>
  boilerplate_description() const {
    DCHECK(boilerplate_description_.is_initialized());
1345
    return boilerplate_description_;
1346
  }
1347
  int properties_count() const { return boilerplate_properties_; }
1348
  const ZonePtrList<Property>* properties() const { return &properties_; }
1349
  bool has_elements() const { return HasElementsField::decode(bit_field_); }
1350 1351 1352
  bool has_rest_property() const {
    return HasRestPropertyField::decode(bit_field_);
  }
1353
  bool fast_elements() const { return FastElementsField::decode(bit_field_); }
1354 1355 1356
  bool has_null_prototype() const {
    return HasNullPrototypeField::decode(bit_field_);
  }
1357

1358 1359 1360 1361 1362 1363 1364 1365 1366 1367
  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();
  }

1368 1369
  // Populate the depth field and flags, returns the depth.
  int InitDepthAndFlags();
1370

1371
  // Get the boilerplate description, populating it if necessary.
1372 1373 1374
  template <typename Isolate>
  HandleFor<Isolate, ObjectBoilerplateDescription>
  GetOrBuildBoilerplateDescription(Isolate* isolate) {
1375 1376
    if (boilerplate_description_.is_null()) {
      BuildBoilerplateDescription(isolate);
1377
    }
1378
    return boilerplate_description();
1379 1380
  }

1381
  // Populate the boilerplate description.
1382
  template <typename Isolate>
1383
  void BuildBoilerplateDescription(Isolate* isolate);
1384

1385 1386 1387
  // 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.
1388
  void CalculateEmitStore(Zone* zone);
1389

1390
  // Determines whether the {CreateShallowObjectLiteratal} builtin can be used.
1391 1392
  bool IsFastCloningSupported() const;

1393
  // Assemble bitfield of flags for the CreateObjectLiteral helper.
1394
  int ComputeFlags(bool disable_mementos = false) const {
1395 1396
    int flags = AggregateLiteral::ComputeFlags(disable_mementos);
    if (fast_elements()) flags |= kFastElements;
1397 1398 1399 1400 1401
    if (has_null_prototype()) flags |= kHasNullPrototype;
    return flags;
  }

  int EncodeLiteralType() {
1402 1403
    int flags = kNoFlags;
    if (fast_elements()) flags |= kFastElements;
1404
    if (has_null_prototype()) flags |= kHasNullPrototype;
1405 1406 1407
    return flags;
  }

1408
  enum Flags {
1409 1410
    kFastElements = 1 << 3,
    kHasNullPrototype = 1 << 4,
1411
  };
1412 1413 1414
  STATIC_ASSERT(
      static_cast<int>(AggregateLiteral::kNeedsInitialAllocationSite) <
      static_cast<int>(kFastElements));
1415

1416 1417 1418
 private:
  friend class AstNodeFactory;

1419
  ObjectLiteral(Zone* zone, const ScopedPtrList<Property>& properties,
1420
                uint32_t boilerplate_properties, int pos,
1421
                bool has_rest_property)
1422
      : AggregateLiteral(pos, kObjectLiteral),
1423
        boilerplate_properties_(boilerplate_properties),
1424
        properties_(0, nullptr) {
1425
    bit_field_ |= HasElementsField::encode(false) |
1426
                  HasRestPropertyField::encode(has_rest_property) |
1427
                  FastElementsField::encode(false) |
1428
                  HasNullPrototypeField::encode(false);
1429
    properties.CopyTo(&properties_, zone);
1430
  }
1431

1432 1433 1434 1435 1436
  void InitFlagsForPendingNullPrototype(int i);

  void set_has_elements(bool has_elements) {
    bit_field_ = HasElementsField::update(bit_field_, has_elements);
  }
1437 1438 1439
  void set_fast_elements(bool fast_elements) {
    bit_field_ = FastElementsField::update(bit_field_, fast_elements);
  }
1440 1441 1442
  void set_has_null_protoype(bool has_null_prototype) {
    bit_field_ = HasNullPrototypeField::update(bit_field_, has_null_prototype);
  }
1443
  uint32_t boilerplate_properties_;
1444 1445
  HandleOrOffThreadHandle<ObjectBoilerplateDescription>
      boilerplate_description_;
1446
  ZoneList<Property*> properties_;
1447

1448 1449 1450 1451
  using HasElementsField = AggregateLiteral::NextBitField<bool, 1>;
  using HasRestPropertyField = HasElementsField::Next<bool, 1>;
  using FastElementsField = HasRestPropertyField::Next<bool, 1>;
  using HasNullPrototypeField = FastElementsField::Next<bool, 1>;
1452 1453 1454
};

// An array literal has a literals object that is used
1455
// for minimizing the work when constructing it at runtime.
1456
class ArrayLiteral final : public AggregateLiteral {
1457
 public:
1458 1459
  HandleOrOffThreadHandle<ArrayBoilerplateDescription> boilerplate_description()
      const {
1460
    return boilerplate_description_;
1461
  }
1462

1463
  const ZonePtrList<Expression>* values() const { return &values_; }
1464

1465 1466
  int first_spread_index() const { return first_spread_index_; }

1467 1468
  // Populate the depth field and flags, returns the depth.
  int InitDepthAndFlags();
1469

1470
  // Get the boilerplate description, populating it if necessary.
1471 1472 1473
  template <typename Isolate>
  HandleFor<Isolate, ArrayBoilerplateDescription>
  GetOrBuildBoilerplateDescription(Isolate* isolate) {
1474 1475
    if (boilerplate_description_.is_null()) {
      BuildBoilerplateDescription(isolate);
1476
    }
1477
    return boilerplate_description_.get<Isolate>();
1478 1479
  }

1480
  // Populate the boilerplate description.
1481
  template <typename Isolate>
1482
  void BuildBoilerplateDescription(Isolate* isolate);
1483

1484
  // Determines whether the {CreateShallowArrayLiteral} builtin can be used.
1485 1486
  bool IsFastCloningSupported() const;

1487
  // Assemble bitfield of flags for the CreateArrayLiteral helper.
1488
  int ComputeFlags(bool disable_mementos = false) const {
1489
    return AggregateLiteral::ComputeFlags(disable_mementos);
1490 1491
  }

1492 1493 1494
 private:
  friend class AstNodeFactory;

1495 1496
  ArrayLiteral(Zone* zone, const ScopedPtrList<Expression>& values,
               int first_spread_index, int pos)
1497
      : AggregateLiteral(pos, kArrayLiteral),
1498
        first_spread_index_(first_spread_index),
1499
        values_(0, nullptr) {
1500
    values.CopyTo(&values_, zone);
1501
  }
1502

1503
  int first_spread_index_;
1504
  HandleOrOffThreadHandle<ArrayBoilerplateDescription> boilerplate_description_;
1505
  ZonePtrList<Expression> values_;
1506 1507
};

1508
enum class HoleCheckMode { kRequired, kElided };
1509

1510 1511 1512 1513 1514 1515
class ThisExpression final : public Expression {
 private:
  friend class AstNodeFactory;
  ThisExpression() : Expression(kNoSourcePosition, kThisExpression) {}
};

1516
class VariableProxy final : public Expression {
1517
 public:
1518
  bool IsValidReferenceExpression() const { return !is_new_target(); }
1519

1520
  Handle<String> name() const { return raw_name()->string(); }
1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533
  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;
  }
1534

1535 1536 1537 1538
  Scanner::Location location() {
    return Scanner::Location(position(), position() + raw_name()->length());
  }

1539 1540 1541
  bool is_assigned() const { return IsAssignedField::decode(bit_field_); }
  void set_is_assigned() {
    bit_field_ = IsAssignedField::update(bit_field_, true);
1542
    if (is_resolved()) {
1543
      var()->SetMaybeAssigned();
1544
    }
1545
  }
1546 1547 1548
  void clear_is_assigned() {
    bit_field_ = IsAssignedField::update(bit_field_, false);
  }
1549

1550 1551 1552 1553
  bool is_resolved() const { return IsResolvedField::decode(bit_field_); }
  void set_is_resolved() {
    bit_field_ = IsResolvedField::update(bit_field_, true);
  }
1554

1555 1556 1557 1558 1559
  bool is_new_target() const { return IsNewTargetField::decode(bit_field_); }
  void set_is_new_target() {
    bit_field_ = IsNewTargetField::update(bit_field_, true);
  }

1560
  HoleCheckMode hole_check_mode() const {
1561 1562 1563 1564 1565
    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;
1566 1567
  }
  void set_needs_hole_check() {
1568 1569
    bit_field_ =
        HoleCheckModeField::update(bit_field_, HoleCheckMode::kRequired);
1570 1571
  }

1572 1573
  bool IsPrivateName() const {
    return raw_name()->length() > 0 && raw_name()->FirstCharacter() == '#';
1574 1575
  }

1576
  // Bind this proxy to the variable var.
1577 1578
  void BindTo(Variable* var);

1579
  V8_INLINE VariableProxy* next_unresolved() { return next_unresolved_; }
1580 1581 1582 1583 1584 1585 1586
  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);
  }
1587

1588
  // Provides filtered access to the unresolved variable proxy threaded list.
1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601
  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()); }
1602 1603
  };

1604 1605 1606
 private:
  friend class AstNodeFactory;

1607
  VariableProxy(Variable* var, int start_position);
1608

1609
  VariableProxy(const AstRawString* name, VariableKind variable_kind,
1610 1611 1612
                int start_position)
      : Expression(start_position, kVariableProxy),
        raw_name_(name),
1613
        next_unresolved_(nullptr) {
1614 1615
    DCHECK_NE(THIS_VARIABLE, variable_kind);
    bit_field_ |= IsAssignedField::encode(false) |
1616
                  IsResolvedField::encode(false) |
1617
                  IsRemovedFromUnresolvedField::encode(false) |
1618
                  HoleCheckModeField::encode(HoleCheckMode::kElided);
1619 1620
  }

1621
  explicit VariableProxy(const VariableProxy* copy_from);
1622

1623 1624 1625 1626 1627
  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>;
1628

1629 1630 1631 1632
  union {
    const AstRawString* raw_name_;  // if !is_resolved_
    Variable* var_;                 // if is_resolved_
  };
1633 1634

  V8_INLINE VariableProxy** next() { return &next_unresolved_; }
1635
  VariableProxy* next_unresolved_;
1636

1637
  friend base::ThreadedListTraits<VariableProxy>;
1638
};
1639

1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653
// 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_;
};

1654 1655 1656 1657
// 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 {
1658 1659 1660 1661 1662 1663 1664 1665 1666
  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
1667 1668
};

1669
class Property final : public Expression {
1670
 public:
1671 1672 1673 1674
  bool is_optional_chain_link() const {
    return IsOptionalChainLinkField::decode(bit_field_);
  }

1675
  bool IsValidReferenceExpression() const { return true; }
1676 1677 1678 1679

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

1680
  bool IsSuperAccess() { return obj()->IsSuperPropertyReference(); }
1681
  bool IsPrivateReference() const { return key()->IsPrivateName(); }
1682

1683
  // Returns the properties assign type.
1684 1685
  static AssignType GetAssignType(Property* property) {
    if (property == nullptr) return NON_PROPERTY;
1686 1687 1688 1689 1690
    if (property->IsPrivateReference()) {
      DCHECK(!property->IsSuperAccess());
      VariableProxy* proxy = property->key()->AsVariableProxy();
      DCHECK_NOT_NULL(proxy);
      Variable* var = proxy->var();
1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705

      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();
      }
1706
    }
1707
    bool super_access = property->IsSuperAccess();
1708
    return (property->key()->IsPropertyName())
1709 1710 1711 1712
               ? (super_access ? NAMED_SUPER_PROPERTY : NAMED_PROPERTY)
               : (super_access ? KEYED_SUPER_PROPERTY : KEYED_PROPERTY);
  }

1713 1714 1715
 private:
  friend class AstNodeFactory;

1716
  Property(Expression* obj, Expression* key, int pos, bool optional_chain)
1717
      : Expression(pos, kProperty), obj_(obj), key_(key) {
1718
    bit_field_ |= IsOptionalChainLinkField::encode(optional_chain);
1719
  }
1720

1721 1722
  using IsOptionalChainLinkField = Expression::NextBitField<bool, 1>;

1723 1724
  Expression* obj_;
  Expression* key_;
1725 1726
};

1727
class Call final : public Expression {
1728 1729
 public:
  Expression* expression() const { return expression_; }
1730
  const ZonePtrList<Expression>* arguments() const { return &arguments_; }
1731

1732 1733 1734 1735
  bool is_possibly_eval() const {
    return IsPossiblyEvalField::decode(bit_field_);
  }

1736 1737 1738 1739
  bool is_tagged_template() const {
    return IsTaggedTemplateField::decode(bit_field_);
  }

1740 1741 1742 1743
  bool is_optional_chain_link() const {
    return IsOptionalChainLinkField::decode(bit_field_);
  }

1744
  bool only_last_arg_is_spread() {
1745
    return !arguments_.is_empty() && arguments_.last()->IsSpread();
1746 1747
  }

1748 1749
  enum CallType {
    GLOBAL_CALL,
1750
    WITH_CALL,
1751 1752
    NAMED_PROPERTY_CALL,
    KEYED_PROPERTY_CALL,
1753 1754
    NAMED_OPTIONAL_CHAIN_PROPERTY_CALL,
    KEYED_OPTIONAL_CHAIN_PROPERTY_CALL,
1755 1756
    NAMED_SUPER_PROPERTY_CALL,
    KEYED_SUPER_PROPERTY_CALL,
1757
    PRIVATE_CALL,
1758
    SUPER_CALL,
1759
    OTHER_CALL,
1760 1761
  };

1762 1763 1764 1765 1766
  enum PossiblyEval {
    IS_POSSIBLY_EVAL,
    NOT_EVAL,
  };

1767
  // Helpers to determine how to handle the call.
1768
  CallType GetCallType() const;
1769

1770 1771
  enum class TaggedTemplateTag { kTrue };

1772 1773 1774
 private:
  friend class AstNodeFactory;

1775 1776
  Call(Zone* zone, Expression* expression,
       const ScopedPtrList<Expression>& arguments, int pos,
1777
       PossiblyEval possibly_eval, bool optional_chain)
1778 1779 1780
      : Expression(pos, kCall),
        expression_(expression),
        arguments_(0, nullptr) {
1781
    bit_field_ |=
1782
        IsPossiblyEvalField::encode(possibly_eval == IS_POSSIBLY_EVAL) |
1783 1784
        IsTaggedTemplateField::encode(false) |
        IsOptionalChainLinkField::encode(optional_chain);
1785
    arguments.CopyTo(&arguments_, zone);
1786 1787
  }

1788 1789 1790
  Call(Zone* zone, Expression* expression,
       const ScopedPtrList<Expression>& arguments, int pos,
       TaggedTemplateTag tag)
1791 1792 1793
      : Expression(pos, kCall),
        expression_(expression),
        arguments_(0, nullptr) {
1794
    bit_field_ |= IsPossiblyEvalField::encode(false) |
1795 1796
                  IsTaggedTemplateField::encode(true) |
                  IsOptionalChainLinkField::encode(false);
1797
    arguments.CopyTo(&arguments_, zone);
verwaest@chromium.org's avatar
verwaest@chromium.org committed
1798
  }
1799

1800 1801
  using IsPossiblyEvalField = Expression::NextBitField<bool, 1>;
  using IsTaggedTemplateField = IsPossiblyEvalField::Next<bool, 1>;
1802
  using IsOptionalChainLinkField = IsTaggedTemplateField::Next<bool, 1>;
1803

1804
  Expression* expression_;
1805
  ZonePtrList<Expression> arguments_;
1806
};
1807

1808

1809
class CallNew final : public Expression {
1810
 public:
1811
  Expression* expression() const { return expression_; }
1812
  const ZonePtrList<Expression>* arguments() const { return &arguments_; }
1813

1814
  bool only_last_arg_is_spread() {
1815
    return !arguments_.is_empty() && arguments_.last()->IsSpread();
1816 1817
  }

1818 1819 1820
 private:
  friend class AstNodeFactory;

1821 1822
  CallNew(Zone* zone, Expression* expression,
          const ScopedPtrList<Expression>& arguments, int pos)
1823
      : Expression(pos, kCallNew),
1824
        expression_(expression),
1825
        arguments_(0, nullptr) {
1826
    arguments.CopyTo(&arguments_, zone);
1827
  }
1828

1829
  Expression* expression_;
1830
  ZonePtrList<Expression> arguments_;
1831 1832
};

1833 1834 1835
// 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
1836
// implemented in JavaScript.
1837
class CallRuntime final : public Expression {
1838
 public:
1839
  const ZonePtrList<Expression>* arguments() const { return &arguments_; }
1840
  bool is_jsruntime() const { return function_ == nullptr; }
1841

1842 1843 1844
  int context_index() const {
    DCHECK(is_jsruntime());
    return context_index_;
1845
  }
1846 1847 1848
  const Runtime::Function* function() const {
    DCHECK(!is_jsruntime());
    return function_;
1849 1850
  }

1851
  const char* debug_name();
1852

1853 1854 1855
 private:
  friend class AstNodeFactory;

1856
  CallRuntime(Zone* zone, const Runtime::Function* function,
1857
              const ScopedPtrList<Expression>& arguments, int pos)
1858
      : Expression(pos, kCallRuntime),
1859
        function_(function),
1860
        arguments_(0, nullptr) {
1861
    arguments.CopyTo(&arguments_, zone);
1862
  }
1863 1864
  CallRuntime(Zone* zone, int context_index,
              const ScopedPtrList<Expression>& arguments, int pos)
1865
      : Expression(pos, kCallRuntime),
1866
        context_index_(context_index),
1867
        function_(nullptr),
1868
        arguments_(0, nullptr) {
1869
    arguments.CopyTo(&arguments_, zone);
1870
  }
1871 1872

  int context_index_;
1873
  const Runtime::Function* function_;
1874
  ZonePtrList<Expression> arguments_;
1875 1876 1877
};


1878
class UnaryOperation final : public Expression {
1879
 public:
1880
  Token::Value op() const { return OperatorField::decode(bit_field_); }
1881 1882
  Expression* expression() const { return expression_; }

1883 1884 1885
 private:
  friend class AstNodeFactory;

1886
  UnaryOperation(Token::Value op, Expression* expression, int pos)
1887 1888
      : Expression(pos, kUnaryOperation), expression_(expression) {
    bit_field_ |= OperatorField::encode(op);
1889
    DCHECK(Token::IsUnaryOp(op));
1890
  }
1891

1892
  Expression* expression_;
1893

1894
  using OperatorField = Expression::NextBitField<Token::Value, 7>;
1895 1896 1897
};


1898
class BinaryOperation final : public Expression {
1899
 public:
1900
  Token::Value op() const { return OperatorField::decode(bit_field_); }
1901 1902 1903
  Expression* left() const { return left_; }
  Expression* right() const { return right_; }

1904 1905
  // Returns true if one side is a Smi literal, returning the other side's
  // sub-expression in |subexpr| and the literal Smi in |literal|.
1906
  bool IsSmiLiteralOperation(Expression** subexpr, Smi* literal);
1907

1908 1909 1910
 private:
  friend class AstNodeFactory;

1911
  BinaryOperation(Token::Value op, Expression* left, Expression* right, int pos)
1912
      : Expression(pos, kBinaryOperation), left_(left), right_(right) {
1913
    bit_field_ |= OperatorField::encode(op);
1914
    DCHECK(Token::IsBinaryOp(op));
1915
  }
1916

1917 1918
  Expression* left_;
  Expression* right_;
1919

1920
  using OperatorField = Expression::NextBitField<Token::Value, 7>;
1921 1922
};

1923 1924 1925 1926 1927
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 {
1928
    return subsequent_[index].expression;
1929 1930
  }

1931
  size_t subsequent_length() const { return subsequent_.size(); }
1932
  int subsequent_op_position(size_t index) const {
1933
    return subsequent_[index].op_position;
1934 1935 1936 1937 1938 1939 1940 1941 1942 1943
  }

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

 private:
  friend class AstNodeFactory;

  NaryOperation(Zone* zone, Token::Value op, Expression* first,
1944
                size_t initial_subsequent_size)
1945
      : Expression(first->position(), kNaryOperation),
1946 1947 1948 1949 1950
        first_(first),
        subsequent_(zone) {
    bit_field_ |= OperatorField::encode(op);
    DCHECK(Token::IsBinaryOp(op));
    DCHECK_NE(op, Token::EXP);
1951
    subsequent_.reserve(initial_subsequent_size);
1952 1953
  }

1954 1955 1956 1957
  // 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.
1958 1959 1960
  //
  // So an nary add:
  //
1961
  //    expr + expr + expr + ...
1962 1963 1964
  //
  // is stored as:
  //
1965 1966 1967
  //    (expr) [(+ expr), (+ expr), ...]
  //    '-.--' '-----------.-----------'
  //    first    subsequent entry list
1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978

  Expression* first_;

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

1979
  using OperatorField = Expression::NextBitField<Token::Value, 7>;
1980
};
1981

1982
class CountOperation final : public Expression {
1983
 public:
1984 1985
  bool is_prefix() const { return IsPrefixField::decode(bit_field_); }
  bool is_postfix() const { return !is_prefix(); }
1986

1987
  Token::Value op() const { return TokenField::decode(bit_field_); }
1988

1989
  Expression* expression() const { return expression_; }
1990

1991 1992 1993
 private:
  friend class AstNodeFactory;

1994
  CountOperation(Token::Value op, bool is_prefix, Expression* expr, int pos)
1995
      : Expression(pos, kCountOperation), expression_(expr) {
1996
    bit_field_ |= IsPrefixField::encode(is_prefix) | TokenField::encode(op);
1997
  }
1998

1999 2000
  using IsPrefixField = Expression::NextBitField<bool, 1>;
  using TokenField = IsPrefixField::Next<Token::Value, 7>;
2001

2002
  Expression* expression_;
2003 2004 2005
};


2006
class CompareOperation final : public Expression {
2007
 public:
2008
  Token::Value op() const { return OperatorField::decode(bit_field_); }
2009 2010 2011
  Expression* left() const { return left_; }
  Expression* right() const { return right_; }

2012
  // Match special cases.
2013
  bool IsLiteralCompareTypeof(Expression** expr, Literal** literal);
2014
  bool IsLiteralCompareUndefined(Expression** expr);
2015
  bool IsLiteralCompareNull(Expression** expr);
2016

2017 2018 2019
 private:
  friend class AstNodeFactory;

2020 2021
  CompareOperation(Token::Value op, Expression* left, Expression* right,
                   int pos)
2022
      : Expression(pos, kCompareOperation), left_(left), right_(right) {
2023
    bit_field_ |= OperatorField::encode(op);
2024
    DCHECK(Token::IsCompareOp(op));
2025
  }
2026

2027 2028
  Expression* left_;
  Expression* right_;
2029

2030
  using OperatorField = Expression::NextBitField<Token::Value, 7>;
2031 2032 2033
};


2034
class Spread final : public Expression {
2035 2036 2037
 public:
  Expression* expression() const { return expression_; }

nikolaos's avatar
nikolaos committed
2038 2039
  int expression_position() const { return expr_pos_; }

2040 2041 2042
 private:
  friend class AstNodeFactory;

2043 2044
  Spread(Expression* expression, int pos, int expr_pos)
      : Expression(pos, kSpread),
2045 2046
        expr_pos_(expr_pos),
        expression_(expression) {}
2047

nikolaos's avatar
nikolaos committed
2048
  int expr_pos_;
2049
  Expression* expression_;
2050 2051
};

2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074
// The StoreInArrayLiteral node corresponds to the StaInArrayLiteral bytecode.
// It is used in the rewriting of destructuring assignments that contain an
// array rest pattern.
class StoreInArrayLiteral final : public Expression {
 public:
  Expression* array() const { return array_; }
  Expression* index() const { return index_; }
  Expression* value() const { return value_; }

 private:
  friend class AstNodeFactory;

  StoreInArrayLiteral(Expression* array, Expression* index, Expression* value,
                      int position)
      : Expression(position, kStoreInArrayLiteral),
        array_(array),
        index_(index),
        value_(value) {}

  Expression* array_;
  Expression* index_;
  Expression* value_;
};
2075

2076
class Conditional final : public Expression {
2077
 public:
2078 2079 2080 2081
  Expression* condition() const { return condition_; }
  Expression* then_expression() const { return then_expression_; }
  Expression* else_expression() const { return else_expression_; }

2082 2083 2084
 private:
  friend class AstNodeFactory;

2085
  Conditional(Expression* condition, Expression* then_expression,
2086
              Expression* else_expression, int position)
2087
      : Expression(position, kConditional),
2088
        condition_(condition),
2089
        then_expression_(then_expression),
2090
        else_expression_(else_expression) {}
2091

2092 2093 2094 2095 2096
  Expression* condition_;
  Expression* then_expression_;
  Expression* else_expression_;
};

2097
class Assignment : public Expression {
2098
 public:
2099
  Token::Value op() const { return TokenField::decode(bit_field_); }
2100 2101
  Expression* target() const { return target_; }
  Expression* value() const { return value_; }
2102

2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114
  // 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));
  }

2115 2116 2117 2118
 protected:
  Assignment(NodeType type, Token::Value op, Expression* target,
             Expression* value, int pos);

2119 2120 2121
 private:
  friend class AstNodeFactory;

2122 2123
  using TokenField = Expression::NextBitField<Token::Value, 7>;
  using LookupHoistingModeField = TokenField::Next<bool, 1>;
2124

2125 2126
  Expression* target_;
  Expression* value_;
2127 2128
};

2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142
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_;
};
2143

2144 2145 2146 2147 2148 2149
// There are several types of Suspend node:
//
// Yield
// YieldStar
// Await
//
2150 2151 2152
// 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).
2153
class Suspend : public Expression {
2154
 public:
2155 2156 2157
  // 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*.
2158 2159 2160
  // TODO(caitp): remove once yield* desugaring for async generators is handled
  // in BytecodeGenerator.
  enum OnAbruptResume { kOnExceptionThrow, kNoControl };
2161

2162
  Expression* expression() const { return expression_; }
2163 2164
  OnAbruptResume on_abrupt_resume() const {
    return OnAbruptResumeField::decode(bit_field_);
2165
  }
2166

2167 2168
 private:
  friend class AstNodeFactory;
2169
  friend class Yield;
2170
  friend class YieldStar;
2171
  friend class Await;
2172

2173
  Suspend(NodeType node_type, Expression* expression, int pos,
2174
          OnAbruptResume on_abrupt_resume)
2175
      : Expression(pos, node_type), expression_(expression) {
2176
    bit_field_ |= OnAbruptResumeField::encode(on_abrupt_resume);
2177
  }
2178

2179
  Expression* expression_;
2180

2181
  using OnAbruptResumeField = Expression::NextBitField<OnAbruptResume, 1>;
2182 2183 2184 2185 2186 2187
};

class Yield final : public Suspend {
 private:
  friend class AstNodeFactory;
  Yield(Expression* expression, int pos, OnAbruptResume on_abrupt_resume)
2188
      : Suspend(kYield, expression, pos, on_abrupt_resume) {}
2189 2190
};

2191 2192 2193
class YieldStar final : public Suspend {
 private:
  friend class AstNodeFactory;
2194
  YieldStar(Expression* expression, int pos)
2195
      : Suspend(kYieldStar, expression, pos,
2196
                Suspend::OnAbruptResume::kNoControl) {}
2197
};
2198

2199 2200 2201 2202
class Await final : public Suspend {
 private:
  friend class AstNodeFactory;

2203
  Await(Expression* expression, int pos)
2204
      : Suspend(kAwait, expression, pos, Suspend::kOnExceptionThrow) {}
2205 2206
};

2207
class Throw final : public Expression {
2208 2209
 public:
  Expression* exception() const { return exception_; }
2210

2211 2212 2213
 private:
  friend class AstNodeFactory;

2214 2215
  Throw(Expression* exception, int pos)
      : Expression(pos, kThrow), exception_(exception) {}
2216 2217 2218 2219 2220

  Expression* exception_;
};


2221
class FunctionLiteral final : public Expression {
2222
 public:
2223 2224 2225 2226 2227
  enum ParameterFlag : uint8_t {
    kNoDuplicateParameters,
    kHasDuplicateParameters
  };
  enum EagerCompileHint : uint8_t { kShouldEagerCompile, kShouldLazyCompile };
2228

2229 2230
  // 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).
2231 2232
  MaybeHandle<String> GetName(Isolate* isolate) const {
    return raw_name_ ? raw_name_->AllocateFlat(isolate) : MaybeHandle<String>();
2233 2234
  }
  bool has_shared_name() const { return raw_name_ != nullptr; }
2235 2236
  const AstConsString* raw_name() const { return raw_name_; }
  void set_raw_name(const AstConsString* name) { raw_name_ = name; }
2237
  DeclarationScope* scope() const { return scope_; }
2238
  ZonePtrList<Statement>* body() { return &body_; }
2239 2240
  void set_function_token_position(int pos) { function_token_position_ = pos; }
  int function_token_position() const { return function_token_position_; }
2241 2242
  int start_position() const;
  int end_position() const;
2243
  bool is_anonymous_expression() const {
2244
    return syntax_kind() == FunctionSyntaxKind::kAnonymousExpression;
2245
  }
2246

2247 2248 2249 2250
  void mark_as_oneshot_iife() {
    bit_field_ = OneshotIIFEBit::update(bit_field_, true);
  }
  bool is_oneshot_iife() const { return OneshotIIFEBit::decode(bit_field_); }
2251
  bool is_toplevel() const {
2252
    return function_literal_id() == kFunctionLiteralIdTopLevel;
2253
  }
2254
  V8_EXPORT_PRIVATE LanguageMode language_mode() const;
2255

2256
  static bool NeedsHomeObject(Expression* expr);
2257

2258 2259
  void add_expected_properties(int number_properties) {
    expected_property_count_ += number_properties;
2260
  }
2261
  int expected_property_count() { return expected_property_count_; }
2262
  int parameter_count() { return parameter_count_; }
2263
  int function_length() { return function_length_; }
2264 2265 2266

  bool AllowsLazyCompilation();

2267 2268 2269 2270 2271 2272 2273 2274
  bool CanSuspend() {
    if (suspend_count() > 0) {
      DCHECK(IsResumableFunction(kind()));
      return true;
    }
    return false;
  }

2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286
  // 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;

2287 2288
  // Returns either name or inferred name as a cstring.
  std::unique_ptr<char[]> GetDebugName() const;
2289

2290
  Handle<String> GetInferredName(Isolate* isolate) {
2291
    if (!inferred_name_.is_null()) {
2292
      DCHECK_NULL(raw_inferred_name_);
2293 2294
      return inferred_name_;
    }
2295
    if (raw_inferred_name_ != nullptr) {
2296
      return raw_inferred_name_->GetString(isolate);
2297 2298 2299
    }
    UNREACHABLE();
  }
2300 2301
  const AstConsString* raw_inferred_name() { return raw_inferred_name_; }

2302 2303
  // Only one of {set_inferred_name, set_raw_inferred_name} should be called.
  void set_inferred_name(Handle<String> inferred_name);
2304
  void set_raw_inferred_name(AstConsString* raw_inferred_name);
2305

2306 2307
  bool pretenure() const { return Pretenure::decode(bit_field_); }
  void set_pretenure() { bit_field_ = Pretenure::update(bit_field_, true); }
2308

2309
  bool has_duplicate_parameters() const {
2310
    // Not valid for lazy functions.
2311
    DCHECK(ShouldEagerCompile());
2312
    return HasDuplicateParameters::decode(bit_field_);
2313
  }
2314

2315 2316 2317 2318 2319
  // 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() { ... }();
2320
  V8_EXPORT_PRIVATE bool ShouldEagerCompile() const;
2321
  V8_EXPORT_PRIVATE void SetShouldEagerCompile();
2322

2323 2324
  FunctionSyntaxKind syntax_kind() const {
    return FunctionSyntaxKindBits::decode(bit_field_);
2325
  }
2326
  FunctionKind kind() const;
2327

2328 2329 2330
  bool dont_optimize() {
    return dont_optimize_reason() != BailoutReason::kNoReason;
  }
2331
  BailoutReason dont_optimize_reason() {
2332
    return DontOptimizeReasonField::decode(bit_field_);
2333
  }
2334
  void set_dont_optimize_reason(BailoutReason reason) {
2335
    bit_field_ = DontOptimizeReasonField::update(bit_field_, reason);
2336 2337
  }

2338
  bool IsAnonymousFunctionDefinition() const {
2339
    return is_anonymous_expression();
2340 2341
  }

2342 2343
  int suspend_count() { return suspend_count_; }
  void set_suspend_count(int suspend_count) { suspend_count_ = suspend_count; }
2344

2345
  int return_position() {
2346 2347 2348
    return std::max(
        start_position(),
        end_position() - (HasBracesField::decode(bit_field_) ? 1 : 0));
2349 2350
  }

2351 2352 2353 2354 2355
  int function_literal_id() const { return function_literal_id_; }
  void set_function_literal_id(int function_literal_id) {
    function_literal_id_ = function_literal_id;
  }

2356 2357
  void set_requires_instance_members_initializer(bool value) {
    bit_field_ = RequiresInstanceMembersInitializer::update(bit_field_, value);
2358
  }
2359 2360
  bool requires_instance_members_initializer() const {
    return RequiresInstanceMembersInitializer::decode(bit_field_);
2361 2362
  }

2363 2364
  bool requires_brand_initialization() const;

2365 2366
  bool private_name_lookup_skips_outer_class() const;

2367 2368
  ProducedPreparseData* produced_preparse_data() const {
    return produced_preparse_data_;
2369 2370
  }

2371 2372 2373
 private:
  friend class AstNodeFactory;

2374 2375 2376 2377
  FunctionLiteral(Zone* zone, const AstRawString* name,
                  AstValueFactory* ast_value_factory, DeclarationScope* scope,
                  const ScopedPtrList<Statement>& body,
                  int expected_property_count, int parameter_count,
2378
                  int function_length, FunctionSyntaxKind function_syntax_kind,
2379 2380 2381 2382
                  ParameterFlag has_duplicate_parameters,
                  EagerCompileHint eager_compile_hint, int position,
                  bool has_braces, int function_literal_id,
                  ProducedPreparseData* produced_preparse_data = nullptr)
2383
      : Expression(position, kFunctionLiteral),
2384 2385
        expected_property_count_(expected_property_count),
        parameter_count_(parameter_count),
2386
        function_length_(function_length),
yangguo's avatar
yangguo committed
2387
        function_token_position_(kNoSourcePosition),
2388
        suspend_count_(0),
2389
        function_literal_id_(function_literal_id),
2390
        raw_name_(name ? ast_value_factory->NewConsString(name) : nullptr),
2391
        scope_(scope),
2392
        body_(0, nullptr),
2393
        raw_inferred_name_(ast_value_factory->empty_cons_string()),
2394
        produced_preparse_data_(produced_preparse_data) {
2395 2396 2397 2398 2399 2400 2401 2402
    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);
2403
    if (eager_compile_hint == kShouldEagerCompile) SetShouldEagerCompile();
2404
    body.CopyTo(&body_, zone);
2405
  }
2406

2407 2408 2409
  using FunctionSyntaxKindBits =
      Expression::NextBitField<FunctionSyntaxKind, 3>;
  using Pretenure = FunctionSyntaxKindBits::Next<bool, 1>;
2410
  using HasDuplicateParameters = Pretenure::Next<bool, 1>;
2411
  using DontOptimizeReasonField =
2412
      HasDuplicateParameters::Next<BailoutReason, 8>;
2413
  using RequiresInstanceMembersInitializer =
2414 2415 2416
      DontOptimizeReasonField::Next<bool, 1>;
  using HasBracesField = RequiresInstanceMembersInitializer::Next<bool, 1>;
  using OneshotIIFEBit = HasBracesField::Next<bool, 1>;
2417

2418 2419
  // expected_property_count_ is the sum of instance fields and properties.
  // It can vary depending on whether a function is lazily or eagerly parsed.
2420
  int expected_property_count_;
2421
  int parameter_count_;
2422
  int function_length_;
2423
  int function_token_position_;
2424
  int suspend_count_;
2425
  int function_literal_id_;
2426

2427
  const AstConsString* raw_name_;
2428
  DeclarationScope* scope_;
2429
  ZonePtrList<Statement> body_;
2430
  AstConsString* raw_inferred_name_;
2431
  Handle<String> inferred_name_;
2432
  ProducedPreparseData* produced_preparse_data_;
2433 2434
};

2435 2436 2437 2438
// 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:
2439
  enum Kind : uint8_t { METHOD, GETTER, SETTER, FIELD };
2440 2441 2442 2443 2444

  Kind kind() const { return kind_; }

  bool is_static() const { return is_static_; }

2445 2446
  bool is_private() const { return is_private_; }

2447
  void set_computed_name_var(Variable* var) {
2448 2449
    DCHECK_EQ(FIELD, kind());
    DCHECK(!is_private());
2450 2451
    private_or_computed_name_var_ = var;
  }
2452

2453
  Variable* computed_name_var() const {
2454 2455
    DCHECK_EQ(FIELD, kind());
    DCHECK(!is_private());
2456 2457 2458
    return private_or_computed_name_var_;
  }

2459
  void set_private_name_var(Variable* var) {
2460
    DCHECK(is_private());
2461 2462
    private_or_computed_name_var_ = var;
  }
2463
  Variable* private_name_var() const {
2464
    DCHECK(is_private());
2465 2466
    return private_or_computed_name_var_;
  }
2467

2468 2469 2470 2471 2472
  bool NeedsHomeObjectOnClassPrototype() const {
    return is_private() && kind_ == METHOD &&
           FunctionLiteral::NeedsHomeObject(value_);
  }

2473 2474 2475 2476
 private:
  friend class AstNodeFactory;

  ClassLiteralProperty(Expression* key, Expression* value, Kind kind,
2477
                       bool is_static, bool is_computed_name, bool is_private);
2478 2479 2480

  Kind kind_;
  bool is_static_;
2481
  bool is_private_;
2482
  Variable* private_or_computed_name_var_;
2483
};
2484

2485
class InitializeClassMembersStatement final : public Statement {
2486
 public:
2487
  using Property = ClassLiteralProperty;
2488 2489

  ZonePtrList<Property>* fields() const { return fields_; }
2490 2491 2492 2493

 private:
  friend class AstNodeFactory;

2494 2495
  InitializeClassMembersStatement(ZonePtrList<Property>* fields, int pos)
      : Statement(pos, kInitializeClassMembersStatement), fields_(fields) {}
2496

2497
  ZonePtrList<Property>* fields_;
2498 2499
};

2500
class ClassLiteral final : public Expression {
arv@chromium.org's avatar
arv@chromium.org committed
2501
 public:
2502
  using Property = ClassLiteralProperty;
arv@chromium.org's avatar
arv@chromium.org committed
2503

2504
  ClassScope* scope() const { return scope_; }
arv@chromium.org's avatar
arv@chromium.org committed
2505
  Expression* extends() const { return extends_; }
2506
  FunctionLiteral* constructor() const { return constructor_; }
2507 2508
  ZonePtrList<Property>* public_members() const { return public_members_; }
  ZonePtrList<Property>* private_members() const { return private_members_; }
2509 2510
  int start_position() const { return position(); }
  int end_position() const { return end_position_; }
2511 2512 2513 2514 2515 2516
  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
2517

2518 2519 2520
  bool is_anonymous_expression() const {
    return IsAnonymousExpression::decode(bit_field_);
  }
2521 2522 2523
  bool has_private_methods() const {
    return HasPrivateMethods::decode(bit_field_);
  }
2524 2525 2526 2527
  bool IsAnonymousFunctionDefinition() const {
    return is_anonymous_expression();
  }

2528 2529 2530 2531
  FunctionLiteral* static_fields_initializer() const {
    return static_fields_initializer_;
  }

2532 2533
  FunctionLiteral* instance_members_initializer_function() const {
    return instance_members_initializer_function_;
2534 2535
  }

2536 2537
 private:
  friend class AstNodeFactory;
2538

2539
  ClassLiteral(ClassScope* scope, Expression* extends,
2540 2541 2542
               FunctionLiteral* constructor,
               ZonePtrList<Property>* public_members,
               ZonePtrList<Property>* private_members,
2543
               FunctionLiteral* static_fields_initializer,
2544
               FunctionLiteral* instance_members_initializer_function,
2545 2546
               int start_position, int end_position,
               bool has_name_static_property, bool has_static_computed_names,
2547
               bool is_anonymous, bool has_private_methods)
2548
      : Expression(start_position, kClassLiteral),
2549
        end_position_(end_position),
2550
        scope_(scope),
arv@chromium.org's avatar
arv@chromium.org committed
2551 2552
        extends_(extends),
        constructor_(constructor),
2553 2554
        public_members_(public_members),
        private_members_(private_members),
2555
        static_fields_initializer_(static_fields_initializer),
2556 2557
        instance_members_initializer_function_(
            instance_members_initializer_function) {
2558
    bit_field_ |= HasNameStaticProperty::encode(has_name_static_property) |
2559
                  HasStaticComputedNames::encode(has_static_computed_names) |
2560 2561
                  IsAnonymousExpression::encode(is_anonymous) |
                  HasPrivateMethods::encode(has_private_methods);
2562
  }
2563

2564
  int end_position_;
2565
  ClassScope* scope_;
arv@chromium.org's avatar
arv@chromium.org committed
2566
  Expression* extends_;
2567
  FunctionLiteral* constructor_;
2568 2569
  ZonePtrList<Property>* public_members_;
  ZonePtrList<Property>* private_members_;
2570
  FunctionLiteral* static_fields_initializer_;
2571
  FunctionLiteral* instance_members_initializer_function_;
2572 2573 2574
  using HasNameStaticProperty = Expression::NextBitField<bool, 1>;
  using HasStaticComputedNames = HasNameStaticProperty::Next<bool, 1>;
  using IsAnonymousExpression = HasStaticComputedNames::Next<bool, 1>;
2575
  using HasPrivateMethods = IsAnonymousExpression::Next<bool, 1>;
arv@chromium.org's avatar
arv@chromium.org committed
2576 2577 2578
};


2579
class NativeFunctionLiteral final : public Expression {
2580
 public:
2581
  Handle<String> name() const { return name_->string(); }
2582
  const AstRawString* raw_name() const { return name_; }
2583
  v8::Extension* extension() const { return extension_; }
2584

2585 2586 2587
 private:
  friend class AstNodeFactory;

2588 2589 2590
  NativeFunctionLiteral(const AstRawString* name, v8::Extension* extension,
                        int pos)
      : Expression(pos, kNativeFunctionLiteral),
2591 2592
        name_(name),
        extension_(extension) {}
2593

2594
  const AstRawString* name_;
2595
  v8::Extension* extension_;
2596 2597 2598
};


2599
class SuperPropertyReference final : public Expression {
2600
 public:
2601
  Expression* home_object() const { return home_object_; }
2602

2603 2604 2605
 private:
  friend class AstNodeFactory;

2606 2607 2608
  // 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) {
2609
    DCHECK(home_object->IsProperty());
2610
  }
2611

2612
  Expression* home_object_;
2613 2614 2615
};


2616 2617 2618 2619 2620
class SuperCallReference final : public Expression {
 public:
  VariableProxy* new_target_var() const { return new_target_var_; }
  VariableProxy* this_function_var() const { return this_function_var_; }

2621 2622 2623
 private:
  friend class AstNodeFactory;

2624 2625
  // We take in ThisExpression* only as a proof that it was accessed.
  SuperCallReference(VariableProxy* new_target_var,
2626
                     VariableProxy* this_function_var, int pos)
2627
      : Expression(pos, kSuperCallReference),
2628 2629
        new_target_var_(new_target_var),
        this_function_var_(this_function_var) {
2630
    DCHECK(new_target_var->raw_name()->IsOneByteEqualTo(".new.target"));
2631 2632 2633 2634 2635 2636 2637
    DCHECK(this_function_var->raw_name()->IsOneByteEqualTo(".this_function"));
  }

  VariableProxy* new_target_var_;
  VariableProxy* this_function_var_;
};

2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651
// 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_;
};
2652

2653 2654 2655 2656
// 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:
2657 2658
  friend class AstNodeFactory;

2659 2660 2661
  explicit EmptyParentheses(int pos) : Expression(pos, kEmptyParentheses) {
    mark_parenthesized();
  }
2662 2663
};

2664 2665 2666 2667
// Represents the spec operation `GetTemplateObject(templateLiteral)`
// (defined at https://tc39.github.io/ecma262/#sec-gettemplateobject).
class GetTemplateObject final : public Expression {
 public:
2668
  const ZonePtrList<const AstRawString>* cooked_strings() const {
2669 2670
    return cooked_strings_;
  }
2671
  const ZonePtrList<const AstRawString>* raw_strings() const {
2672 2673
    return raw_strings_;
  }
2674

2675 2676 2677
  template <typename Isolate>
  HandleFor<Isolate, TemplateObjectDescription> GetOrBuildDescription(
      Isolate* isolate);
2678 2679 2680 2681

 private:
  friend class AstNodeFactory;

2682 2683
  GetTemplateObject(const ZonePtrList<const AstRawString>* cooked_strings,
                    const ZonePtrList<const AstRawString>* raw_strings, int pos)
2684 2685
      : Expression(pos, kGetTemplateObject),
        cooked_strings_(cooked_strings),
2686
        raw_strings_(raw_strings) {}
2687

2688 2689
  const ZonePtrList<const AstRawString>* cooked_strings_;
  const ZonePtrList<const AstRawString>* raw_strings_;
2690 2691
};

2692 2693
class TemplateLiteral final : public Expression {
 public:
2694 2695 2696 2697 2698 2699
  const ZonePtrList<const AstRawString>* string_parts() const {
    return string_parts_;
  }
  const ZonePtrList<Expression>* substitutions() const {
    return substitutions_;
  }
2700 2701 2702

 private:
  friend class AstNodeFactory;
2703 2704
  TemplateLiteral(const ZonePtrList<const AstRawString>* parts,
                  const ZonePtrList<Expression>* substitutions, int pos)
2705 2706 2707 2708
      : Expression(pos, kTemplateLiteral),
        string_parts_(parts),
        substitutions_(substitutions) {}

2709 2710
  const ZonePtrList<const AstRawString>* string_parts_;
  const ZonePtrList<Expression>* substitutions_;
2711 2712
};

2713 2714
// ----------------------------------------------------------------------------
// Basic visitor
2715 2716
// Sub-class should parametrize AstVisitor with itself, e.g.:
//   class SpecificVisitor : public AstVisitor<SpecificVisitor> { ... }
2717

2718
template <class Subclass>
2719
class AstVisitor {
2720
 public:
2721
  void Visit(AstNode* node) { impl()->Visit(node); }
2722

2723 2724
  void VisitDeclarations(Declaration::List* declarations) {
    for (Declaration* decl : *declarations) Visit(decl);
2725
  }
2726

2727
  void VisitStatements(const ZonePtrList<Statement>* statements) {
2728 2729 2730 2731 2732 2733
    for (int i = 0; i < statements->length(); i++) {
      Statement* stmt = statements->at(i);
      Visit(stmt);
    }
  }

2734
  void VisitExpressions(const ZonePtrList<Expression>* expressions) {
2735
    for (int i = 0; i < expressions->length(); i++) {
2736
      // The variable statement visiting code may pass null expressions
2737
      // to this code. Maybe this should be handled by introducing an
2738 2739
      // undefined expression or literal? Revisit this code if this
      // changes.
2740
      Expression* expression = expressions->at(i);
2741
      if (expression != nullptr) Visit(expression);
2742 2743
    }
  }
2744

2745 2746
 protected:
  Subclass* impl() { return static_cast<Subclass*>(this); }
2747
};
2748

2749 2750 2751
#define GENERATE_VISIT_CASE(NodeType)                                   \
  case AstNode::k##NodeType:                                            \
    return this->impl()->Visit##NodeType(static_cast<NodeType*>(node));
2752

2753 2754 2755 2756 2757 2758 2759 2760
#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) \
2761 2762
  }

2763 2764
#define DEFINE_AST_VISITOR_SUBCLASS_MEMBERS()               \
 public:                                                    \
2765 2766 2767 2768
  void VisitNoStackOverflowCheck(AstNode* node) {           \
    GENERATE_AST_VISITOR_SWITCH()                           \
  }                                                         \
                                                            \
2769 2770
  void Visit(AstNode* node) {                               \
    if (CheckStackOverflow()) return;                       \
2771
    VisitNoStackOverflowCheck(node);                        \
2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786
  }                                                         \
                                                            \
  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;                                           \
  }                                                         \
                                                            \
2787 2788 2789
 protected:                                                 \
  uintptr_t stack_limit() const { return stack_limit_; }    \
                                                            \
2790
 private:                                                   \
2791 2792 2793 2794 2795
  void InitializeAstVisitor(Isolate* isolate) {             \
    stack_limit_ = isolate->stack_guard()->real_climit();   \
    stack_overflow_ = false;                                \
  }                                                         \
                                                            \
2796 2797 2798 2799 2800
  void InitializeAstVisitor(uintptr_t stack_limit) {        \
    stack_limit_ = stack_limit;                             \
    stack_overflow_ = false;                                \
  }                                                         \
                                                            \
2801
  uintptr_t stack_limit_;                                   \
2802
  bool stack_overflow_
2803

2804 2805 2806 2807 2808 2809
#define DEFINE_AST_VISITOR_MEMBERS_WITHOUT_STACKOVERFLOW()    \
 public:                                                      \
  void Visit(AstNode* node) { GENERATE_AST_VISITOR_SWITCH() } \
                                                              \
 private:

2810 2811 2812
// ----------------------------------------------------------------------------
// AstNode factory

2813
class AstNodeFactory final {
2814
 public:
2815
  AstNodeFactory(AstValueFactory* ast_value_factory, Zone* zone)
2816 2817
      : zone_(zone),
        ast_value_factory_(ast_value_factory),
2818
        empty_statement_(new (zone) class EmptyStatement()),
2819
        this_expression_(new (zone) class ThisExpression()),
2820
        failure_expression_(new (zone) class FailureExpression()) {}
2821

2822
  AstNodeFactory* ast_node_factory() { return this; }
neis's avatar
neis committed
2823 2824
  AstValueFactory* ast_value_factory() const { return ast_value_factory_; }

2825 2826
  VariableDeclaration* NewVariableDeclaration(int pos) {
    return new (zone_) VariableDeclaration(pos);
2827 2828
  }

2829
  NestedVariableDeclaration* NewNestedVariableDeclaration(Scope* scope,
2830
                                                          int pos) {
2831
    return new (zone_) NestedVariableDeclaration(scope, pos);
2832 2833
  }

2834 2835
  FunctionDeclaration* NewFunctionDeclaration(FunctionLiteral* fun, int pos) {
    return new (zone_) FunctionDeclaration(fun, pos);
2836 2837
  }

2838 2839 2840 2841 2842 2843
  Block* NewBlock(int capacity, bool ignore_completion_value) {
    return new (zone_) Block(zone_, nullptr, capacity, ignore_completion_value);
  }

  Block* NewBlock(bool ignore_completion_value,
                  ZonePtrList<const AstRawString>* labels) {
2844
    return labels != nullptr
2845 2846 2847 2848 2849 2850 2851 2852 2853
               ? new (zone_) LabeledBlock(labels, ignore_completion_value)
               : new (zone_) Block(labels, ignore_completion_value);
  }

  Block* NewBlock(bool ignore_completion_value,
                  const ScopedPtrList<Statement>& statements) {
    Block* result = NewBlock(ignore_completion_value, nullptr);
    result->InitializeStatements(statements, zone_);
    return result;
2854 2855
  }

2856 2857 2858 2859 2860
#define STATEMENT_WITH_LABELS(NodeType)                                \
  NodeType* New##NodeType(ZonePtrList<const AstRawString>* labels,     \
                          ZonePtrList<const AstRawString>* own_labels, \
                          int pos) {                                   \
    return new (zone_) NodeType(labels, own_labels, pos);              \
2861 2862 2863 2864 2865 2866
  }
  STATEMENT_WITH_LABELS(DoWhileStatement)
  STATEMENT_WITH_LABELS(WhileStatement)
  STATEMENT_WITH_LABELS(ForStatement)
#undef STATEMENT_WITH_LABELS

2867
  SwitchStatement* NewSwitchStatement(ZonePtrList<const AstRawString>* labels,
2868 2869 2870 2871
                                      Expression* tag, int pos) {
    return new (zone_) SwitchStatement(zone_, labels, tag, pos);
  }

2872 2873 2874 2875
  ForEachStatement* NewForEachStatement(
      ForEachStatement::VisitMode visit_mode,
      ZonePtrList<const AstRawString>* labels,
      ZonePtrList<const AstRawString>* own_labels, int pos) {
2876 2877
    switch (visit_mode) {
      case ForEachStatement::ENUMERATE: {
2878
        return new (zone_) ForInStatement(labels, own_labels, pos);
2879 2880
      }
      case ForEachStatement::ITERATE: {
2881 2882
        return new (zone_)
            ForOfStatement(labels, own_labels, pos, IteratorType::kNormal);
2883 2884 2885 2886 2887
      }
    }
    UNREACHABLE();
  }

2888
  ForOfStatement* NewForOfStatement(ZonePtrList<const AstRawString>* labels,
2889
                                    ZonePtrList<const AstRawString>* own_labels,
2890 2891
                                    int pos, IteratorType type) {
    return new (zone_) ForOfStatement(labels, own_labels, pos, type);
2892 2893
  }

2894
  ExpressionStatement* NewExpressionStatement(Expression* expression, int pos) {
2895
    return new (zone_) ExpressionStatement(expression, pos);
2896 2897
  }

2898 2899
  ContinueStatement* NewContinueStatement(IterationStatement* target, int pos) {
    return new (zone_) ContinueStatement(target, pos);
2900 2901
  }

2902 2903
  BreakStatement* NewBreakStatement(BreakableStatement* target, int pos) {
    return new (zone_) BreakStatement(target, pos);
2904 2905
  }

2906 2907 2908 2909
  ReturnStatement* NewReturnStatement(Expression* expression, int pos,
                                      int end_position = kNoSourcePosition) {
    return new (zone_) ReturnStatement(expression, ReturnStatement::kNormal,
                                       pos, end_position);
2910 2911
  }

2912 2913 2914 2915
  ReturnStatement* NewAsyncReturnStatement(
      Expression* expression, int pos, int end_position = kNoSourcePosition) {
    return new (zone_) ReturnStatement(
        expression, ReturnStatement::kAsyncReturn, pos, end_position);
2916 2917
  }

2918 2919 2920 2921 2922 2923
  ReturnStatement* NewSyntheticAsyncReturnStatement(
      Expression* expression, int pos, int end_position = kNoSourcePosition) {
    return new (zone_) ReturnStatement(
        expression, ReturnStatement::kSyntheticAsyncReturn, pos, end_position);
  }

2924 2925
  WithStatement* NewWithStatement(Scope* scope,
                                  Expression* expression,
2926 2927
                                  Statement* statement,
                                  int pos) {
2928
    return new (zone_) WithStatement(scope, expression, statement, pos);
2929 2930
  }

2931
  IfStatement* NewIfStatement(Expression* condition, Statement* then_statement,
2932 2933 2934
                              Statement* else_statement, int pos) {
    return new (zone_)
        IfStatement(condition, then_statement, else_statement, pos);
2935 2936
  }

2937
  TryCatchStatement* NewTryCatchStatement(Block* try_block, Scope* scope,
2938 2939 2940
                                          Block* catch_block, int pos) {
    return new (zone_) TryCatchStatement(try_block, scope, catch_block,
                                         HandlerTable::CAUGHT, pos);
2941 2942 2943 2944 2945 2946
  }

  TryCatchStatement* NewTryCatchStatementForReThrow(Block* try_block,
                                                    Scope* scope,
                                                    Block* catch_block,
                                                    int pos) {
2947
    return new (zone_) TryCatchStatement(try_block, scope, catch_block,
2948
                                         HandlerTable::UNCAUGHT, pos);
2949 2950
  }

2951 2952 2953 2954
  TryCatchStatement* NewTryCatchStatementForDesugaring(Block* try_block,
                                                       Scope* scope,
                                                       Block* catch_block,
                                                       int pos) {
2955
    return new (zone_) TryCatchStatement(try_block, scope, catch_block,
2956
                                         HandlerTable::DESUGARING, pos);
2957 2958
  }

2959 2960 2961 2962
  TryCatchStatement* NewTryCatchStatementForAsyncAwait(Block* try_block,
                                                       Scope* scope,
                                                       Block* catch_block,
                                                       int pos) {
2963
    return new (zone_) TryCatchStatement(try_block, scope, catch_block,
2964
                                         HandlerTable::ASYNC_AWAIT, pos);
2965 2966
  }

2967 2968 2969 2970 2971 2972 2973 2974
  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);
  }

2975 2976 2977
  TryFinallyStatement* NewTryFinallyStatement(Block* try_block,
                                              Block* finally_block, int pos) {
    return new (zone_) TryFinallyStatement(try_block, finally_block, pos);
2978 2979
  }

2980
  DebuggerStatement* NewDebuggerStatement(int pos) {
2981
    return new (zone_) DebuggerStatement(pos);
2982 2983
  }

2984 2985
  class EmptyStatement* EmptyStatement() {
    return empty_statement_;
2986 2987
  }

2988
  class ThisExpression* ThisExpression() {
2989 2990 2991 2992 2993 2994 2995
    // 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();
2996 2997 2998
    return this_expression_;
  }

2999 3000 3001 3002
  class FailureExpression* FailureExpression() {
    return failure_expression_;
  }

3003 3004 3005 3006
  SloppyBlockFunctionStatement* NewSloppyBlockFunctionStatement(
      int pos, Variable* var, Token::Value init) {
    return new (zone_)
        SloppyBlockFunctionStatement(pos, var, init, EmptyStatement());
3007 3008
  }

3009
  CaseClause* NewCaseClause(Expression* label,
3010
                            const ScopedPtrList<Statement>& statements) {
3011
    return new (zone_) CaseClause(zone_, label, statements);
3012 3013
  }

3014
  Literal* NewStringLiteral(const AstRawString* string, int pos) {
3015
    DCHECK_NOT_NULL(string);
3016
    return new (zone_) Literal(string, pos);
3017 3018 3019
  }

  // A JavaScript symbol (ECMA-262 edition 6).
3020
  Literal* NewSymbolLiteral(AstSymbol symbol, int pos) {
3021
    return new (zone_) Literal(symbol, pos);
3022 3023
  }

3024
  Literal* NewNumberLiteral(double number, int pos);
3025

3026 3027
  Literal* NewSmiLiteral(int number, int pos) {
    return new (zone_) Literal(number, pos);
3028 3029
  }

3030 3031
  Literal* NewBigIntLiteral(AstBigInt bigint, int pos) {
    return new (zone_) Literal(bigint, pos);
3032 3033
  }

3034
  Literal* NewBooleanLiteral(bool b, int pos) {
3035
    return new (zone_) Literal(b, pos);
3036 3037 3038
  }

  Literal* NewNullLiteral(int pos) {
3039
    return new (zone_) Literal(Literal::kNull, pos);
3040 3041 3042
  }

  Literal* NewUndefinedLiteral(int pos) {
3043
    return new (zone_) Literal(Literal::kUndefined, pos);
3044 3045
  }

3046
  Literal* NewTheHoleLiteral() {
3047
    return new (zone_) Literal(Literal::kTheHole, kNoSourcePosition);
3048 3049 3050
  }

  ObjectLiteral* NewObjectLiteral(
3051
      const ScopedPtrList<ObjectLiteral::Property>& properties,
3052
      uint32_t boilerplate_properties, int pos, bool has_rest_property) {
3053 3054
    return new (zone_) ObjectLiteral(zone_, properties, boilerplate_properties,
                                     pos, has_rest_property);
3055 3056
  }

3057 3058
  ObjectLiteral::Property* NewObjectLiteralProperty(
      Expression* key, Expression* value, ObjectLiteralProperty::Kind kind,
3059
      bool is_computed_name) {
3060
    return new (zone_)
3061
        ObjectLiteral::Property(key, value, kind, is_computed_name);
3062 3063
  }

arv's avatar
arv committed
3064
  ObjectLiteral::Property* NewObjectLiteralProperty(Expression* key,
arv@chromium.org's avatar
arv@chromium.org committed
3065
                                                    Expression* value,
arv's avatar
arv committed
3066
                                                    bool is_computed_name) {
3067
    return new (zone_) ObjectLiteral::Property(ast_value_factory_, key, value,
3068
                                               is_computed_name);
3069 3070
  }

3071
  RegExpLiteral* NewRegExpLiteral(const AstRawString* pattern, int flags,
3072 3073
                                  int pos) {
    return new (zone_) RegExpLiteral(pattern, flags, pos);
3074 3075
  }

3076 3077
  ArrayLiteral* NewArrayLiteral(const ScopedPtrList<Expression>& values,
                                int pos) {
3078
    return new (zone_) ArrayLiteral(zone_, values, -1, pos);
3079 3080
  }

3081
  ArrayLiteral* NewArrayLiteral(const ScopedPtrList<Expression>& values,
3082
                                int first_spread_index, int pos) {
3083
    return new (zone_) ArrayLiteral(zone_, values, first_spread_index, pos);
3084 3085
  }

3086
  VariableProxy* NewVariableProxy(Variable* var,
3087 3088
                                  int start_position = kNoSourcePosition) {
    return new (zone_) VariableProxy(var, start_position);
3089 3090
  }

3091
  VariableProxy* NewVariableProxy(const AstRawString* name,
3092
                                  VariableKind variable_kind,
3093
                                  int start_position = kNoSourcePosition) {
3094
    DCHECK_NOT_NULL(name);
3095
    return new (zone_) VariableProxy(name, variable_kind, start_position);
3096 3097 3098 3099
  }

  // Recreates the VariableProxy in this Zone.
  VariableProxy* CopyVariableProxy(VariableProxy* proxy) {
3100
    return new (zone_) VariableProxy(proxy);
3101 3102
  }

3103 3104 3105 3106
  Variable* CopyVariable(Variable* variable) {
    return new (zone_) Variable(variable);
  }

3107 3108 3109 3110 3111 3112 3113
  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);
3114 3115
  }

3116 3117
  Call* NewCall(Expression* expression,
                const ScopedPtrList<Expression>& arguments, int pos,
3118 3119 3120 3121
                Call::PossiblyEval possibly_eval = Call::NOT_EVAL,
                bool optional_chain = false) {
    return new (zone_)
        Call(zone_, expression, arguments, pos, possibly_eval, optional_chain);
3122 3123
  }

3124
  Call* NewTaggedTemplate(Expression* expression,
3125
                          const ScopedPtrList<Expression>& arguments, int pos) {
3126
    return new (zone_)
3127
        Call(zone_, expression, arguments, pos, Call::TaggedTemplateTag::kTrue);
3128 3129
  }

3130
  CallNew* NewCallNew(Expression* expression,
3131
                      const ScopedPtrList<Expression>& arguments, int pos) {
3132
    return new (zone_) CallNew(zone_, expression, arguments, pos);
3133 3134
  }

3135
  CallRuntime* NewCallRuntime(Runtime::FunctionId id,
3136 3137
                              const ScopedPtrList<Expression>& arguments,
                              int pos) {
3138 3139
    return new (zone_)
        CallRuntime(zone_, Runtime::FunctionForId(id), arguments, pos);
3140 3141 3142
  }

  CallRuntime* NewCallRuntime(const Runtime::Function* function,
3143 3144
                              const ScopedPtrList<Expression>& arguments,
                              int pos) {
3145
    return new (zone_) CallRuntime(zone_, function, arguments, pos);
3146 3147 3148
  }

  CallRuntime* NewCallRuntime(int context_index,
3149 3150
                              const ScopedPtrList<Expression>& arguments,
                              int pos) {
3151
    return new (zone_) CallRuntime(zone_, context_index, arguments, pos);
3152 3153 3154 3155 3156
  }

  UnaryOperation* NewUnaryOperation(Token::Value op,
                                    Expression* expression,
                                    int pos) {
3157
    return new (zone_) UnaryOperation(op, expression, pos);
3158 3159 3160 3161 3162 3163
  }

  BinaryOperation* NewBinaryOperation(Token::Value op,
                                      Expression* left,
                                      Expression* right,
                                      int pos) {
3164
    return new (zone_) BinaryOperation(op, left, right, pos);
3165 3166
  }

3167
  NaryOperation* NewNaryOperation(Token::Value op, Expression* first,
3168 3169
                                  size_t initial_subsequent_size) {
    return new (zone_) NaryOperation(zone_, op, first, initial_subsequent_size);
3170 3171
  }

3172 3173 3174 3175
  CountOperation* NewCountOperation(Token::Value op,
                                    bool is_prefix,
                                    Expression* expr,
                                    int pos) {
3176
    return new (zone_) CountOperation(op, is_prefix, expr, pos);
3177 3178 3179 3180 3181 3182
  }

  CompareOperation* NewCompareOperation(Token::Value op,
                                        Expression* left,
                                        Expression* right,
                                        int pos) {
3183
    return new (zone_) CompareOperation(op, left, right, pos);
3184 3185
  }

nikolaos's avatar
nikolaos committed
3186
  Spread* NewSpread(Expression* expression, int pos, int expr_pos) {
3187
    return new (zone_) Spread(expression, pos, expr_pos);
3188 3189
  }

3190 3191 3192 3193 3194 3195
  StoreInArrayLiteral* NewStoreInArrayLiteral(Expression* array,
                                              Expression* index,
                                              Expression* value, int pos) {
    return new (zone_) StoreInArrayLiteral(array, index, value, pos);
  }

3196 3197 3198
  Conditional* NewConditional(Expression* condition,
                              Expression* then_expression,
                              Expression* else_expression,
3199
                              int position) {
3200 3201
    return new (zone_)
        Conditional(condition, then_expression, else_expression, position);
3202 3203 3204 3205 3206 3207
  }

  Assignment* NewAssignment(Token::Value op,
                            Expression* target,
                            Expression* value,
                            int pos) {
3208
    DCHECK(Token::IsAssignmentOp(op));
3209 3210
    DCHECK_NOT_NULL(target);
    DCHECK_NOT_NULL(value);
3211 3212 3213 3214 3215

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

3216 3217 3218 3219 3220 3221 3222 3223
    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));
3224
    }
3225 3226
  }

3227 3228
  Suspend* NewYield(Expression* expression, int pos,
                    Suspend::OnAbruptResume on_abrupt_resume) {
3229
    if (!expression) expression = NewUndefinedLiteral(pos);
3230
    return new (zone_) Yield(expression, pos, on_abrupt_resume);
3231 3232
  }

3233 3234
  YieldStar* NewYieldStar(Expression* expression, int pos) {
    return new (zone_) YieldStar(expression, pos);
3235 3236
  }

3237
  Await* NewAwait(Expression* expression, int pos) {
3238
    if (!expression) expression = NewUndefinedLiteral(pos);
3239
    return new (zone_) Await(expression, pos);
3240 3241
  }

3242 3243
  Throw* NewThrow(Expression* exception, int pos) {
    return new (zone_) Throw(exception, pos);
3244 3245 3246
  }

  FunctionLiteral* NewFunctionLiteral(
3247
      const AstRawString* name, DeclarationScope* scope,
3248
      const ScopedPtrList<Statement>& body, int expected_property_count,
3249
      int parameter_count, int function_length,
3250
      FunctionLiteral::ParameterFlag has_duplicate_parameters,
3251
      FunctionSyntaxKind function_syntax_kind,
3252
      FunctionLiteral::EagerCompileHint eager_compile_hint, int position,
3253
      bool has_braces, int function_literal_id,
3254
      ProducedPreparseData* produced_preparse_data = nullptr) {
3255
    return new (zone_) FunctionLiteral(
3256
        zone_, name, ast_value_factory_, scope, body, expected_property_count,
3257
        parameter_count, function_length, function_syntax_kind,
3258
        has_duplicate_parameters, eager_compile_hint, position, has_braces,
3259
        function_literal_id, produced_preparse_data);
3260 3261 3262 3263 3264
  }

  // 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.
3265 3266 3267
  FunctionLiteral* NewScriptOrEvalFunctionLiteral(
      DeclarationScope* scope, const ScopedPtrList<Statement>& body,
      int expected_property_count, int parameter_count) {
3268 3269
    return new (zone_) FunctionLiteral(
        zone_, ast_value_factory_->empty_string(), ast_value_factory_, scope,
3270
        body, expected_property_count, parameter_count, parameter_count,
3271
        FunctionSyntaxKind::kAnonymousExpression,
3272
        FunctionLiteral::kNoDuplicateParameters,
3273
        FunctionLiteral::kShouldLazyCompile, 0, /* has_braces */ false,
3274
        kFunctionLiteralIdTopLevel);
3275 3276
  }

3277 3278
  ClassLiteral::Property* NewClassLiteralProperty(
      Expression* key, Expression* value, ClassLiteralProperty::Kind kind,
3279 3280 3281
      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);
3282 3283
  }

3284
  ClassLiteral* NewClassLiteral(
3285
      ClassScope* scope, Expression* extends, FunctionLiteral* constructor,
3286 3287
      ZonePtrList<ClassLiteral::Property>* public_members,
      ZonePtrList<ClassLiteral::Property>* private_members,
3288
      FunctionLiteral* static_fields_initializer,
3289 3290
      FunctionLiteral* instance_members_initializer_function,
      int start_position, int end_position, bool has_name_static_property,
3291 3292
      bool has_static_computed_names, bool is_anonymous,
      bool has_private_methods) {
3293
    return new (zone_) ClassLiteral(
3294 3295 3296 3297
        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
3298 3299
  }

3300 3301 3302
  NativeFunctionLiteral* NewNativeFunctionLiteral(const AstRawString* name,
                                                  v8::Extension* extension,
                                                  int pos) {
3303
    return new (zone_) NativeFunctionLiteral(name, extension, pos);
3304 3305
  }

3306 3307
  DoExpression* NewDoExpression(Block* block, Variable* result_var, int pos) {
    VariableProxy* result = NewVariableProxy(result_var, pos);
3308
    return new (zone_) DoExpression(block, result, pos);
3309 3310
  }

3311
  SuperPropertyReference* NewSuperPropertyReference(Expression* home_object,
3312
                                                    int pos) {
3313
    return new (zone_) SuperPropertyReference(home_object, pos);
3314 3315
  }

3316
  SuperCallReference* NewSuperCallReference(VariableProxy* new_target_var,
3317 3318
                                            VariableProxy* this_function_var,
                                            int pos) {
3319
    return new (zone_)
3320
        SuperCallReference(new_target_var, this_function_var, pos);
3321 3322
  }

3323
  EmptyParentheses* NewEmptyParentheses(int pos) {
3324
    return new (zone_) EmptyParentheses(pos);
3325 3326
  }

3327
  GetTemplateObject* NewGetTemplateObject(
3328 3329
      const ZonePtrList<const AstRawString>* cooked_strings,
      const ZonePtrList<const AstRawString>* raw_strings, int pos) {
3330
    return new (zone_) GetTemplateObject(cooked_strings, raw_strings, pos);
3331 3332
  }

3333
  TemplateLiteral* NewTemplateLiteral(
3334 3335
      const ZonePtrList<const AstRawString>* string_parts,
      const ZonePtrList<Expression>* substitutions, int pos) {
3336 3337 3338
    return new (zone_) TemplateLiteral(string_parts, substitutions, pos);
  }

3339 3340 3341 3342
  ImportCallExpression* NewImportCallExpression(Expression* args, int pos) {
    return new (zone_) ImportCallExpression(args, pos);
  }

3343
  InitializeClassMembersStatement* NewInitializeClassMembersStatement(
3344
      ZonePtrList<ClassLiteral::Property>* args, int pos) {
3345
    return new (zone_) InitializeClassMembersStatement(args, pos);
3346 3347
  }

3348
  Zone* zone() const { return zone_; }
3349

3350
 private:
3351 3352 3353 3354
  // 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.
3355
  Zone* zone_;
3356
  AstValueFactory* ast_value_factory_;
3357
  class EmptyStatement* empty_statement_;
3358
  class ThisExpression* this_expression_;
3359
  class FailureExpression* failure_expression_;
3360 3361 3362
};


3363 3364 3365
// Type testing & conversion functions overridden by concrete subclasses.
// Inline functions for AstNode.

3366
#define DECLARE_NODE_FUNCTIONS(type)                                         \
3367
  bool AstNode::Is##type() const { return node_type() == AstNode::k##type; } \
3368
  type* AstNode::As##type() {                                                \
3369 3370
    return node_type() == AstNode::k##type ? reinterpret_cast<type*>(this)   \
                                           : nullptr;                        \
3371 3372
  }                                                                          \
  const type* AstNode::As##type() const {                                    \
3373 3374 3375
    return node_type() == AstNode::k##type                                   \
               ? reinterpret_cast<const type*>(this)                         \
               : nullptr;                                                    \
3376 3377
  }
AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
3378
FAILURE_NODE_LIST(DECLARE_NODE_FUNCTIONS)
3379 3380
#undef DECLARE_NODE_FUNCTIONS

3381 3382
}  // namespace internal
}  // namespace v8
3383

3384
#endif  // V8_AST_AST_H_