Home | History | Annotate | Download | only in ast
      1 // Copyright 2012 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef V8_AST_AST_H_
      6 #define V8_AST_AST_H_
      7 
      8 #include "src/ast/ast-types.h"
      9 #include "src/ast/ast-value-factory.h"
     10 #include "src/ast/modules.h"
     11 #include "src/ast/variables.h"
     12 #include "src/bailout-reason.h"
     13 #include "src/base/flags.h"
     14 #include "src/factory.h"
     15 #include "src/globals.h"
     16 #include "src/isolate.h"
     17 #include "src/label.h"
     18 #include "src/list.h"
     19 #include "src/objects/literal-objects.h"
     20 #include "src/parsing/token.h"
     21 #include "src/runtime/runtime.h"
     22 #include "src/small-pointer-list.h"
     23 
     24 namespace v8 {
     25 namespace internal {
     26 
     27 // The abstract syntax tree is an intermediate, light-weight
     28 // representation of the parsed JavaScript code suitable for
     29 // compilation to native code.
     30 
     31 // Nodes are allocated in a separate zone, which allows faster
     32 // allocation and constant-time deallocation of the entire syntax
     33 // tree.
     34 
     35 
     36 // ----------------------------------------------------------------------------
     37 // Nodes of the abstract syntax tree. Only concrete classes are
     38 // enumerated here.
     39 
     40 #define DECLARATION_NODE_LIST(V) \
     41   V(VariableDeclaration)         \
     42   V(FunctionDeclaration)
     43 
     44 #define ITERATION_NODE_LIST(V) \
     45   V(DoWhileStatement)          \
     46   V(WhileStatement)            \
     47   V(ForStatement)              \
     48   V(ForInStatement)            \
     49   V(ForOfStatement)
     50 
     51 #define BREAKABLE_NODE_LIST(V) \
     52   V(Block)                     \
     53   V(SwitchStatement)
     54 
     55 #define STATEMENT_NODE_LIST(V)    \
     56   ITERATION_NODE_LIST(V)          \
     57   BREAKABLE_NODE_LIST(V)          \
     58   V(ExpressionStatement)          \
     59   V(EmptyStatement)               \
     60   V(SloppyBlockFunctionStatement) \
     61   V(IfStatement)                  \
     62   V(ContinueStatement)            \
     63   V(BreakStatement)               \
     64   V(ReturnStatement)              \
     65   V(WithStatement)                \
     66   V(TryCatchStatement)            \
     67   V(TryFinallyStatement)          \
     68   V(DebuggerStatement)
     69 
     70 #define LITERAL_NODE_LIST(V) \
     71   V(RegExpLiteral)           \
     72   V(ObjectLiteral)           \
     73   V(ArrayLiteral)
     74 
     75 #define PROPERTY_NODE_LIST(V) \
     76   V(Assignment)               \
     77   V(CountOperation)           \
     78   V(Property)
     79 
     80 #define CALL_NODE_LIST(V) \
     81   V(Call)                 \
     82   V(CallNew)
     83 
     84 #define EXPRESSION_NODE_LIST(V) \
     85   LITERAL_NODE_LIST(V)          \
     86   PROPERTY_NODE_LIST(V)         \
     87   CALL_NODE_LIST(V)             \
     88   V(FunctionLiteral)            \
     89   V(ClassLiteral)               \
     90   V(NativeFunctionLiteral)      \
     91   V(Conditional)                \
     92   V(VariableProxy)              \
     93   V(Literal)                    \
     94   V(Yield)                      \
     95   V(Throw)                      \
     96   V(CallRuntime)                \
     97   V(UnaryOperation)             \
     98   V(BinaryOperation)            \
     99   V(CompareOperation)           \
    100   V(Spread)                     \
    101   V(ThisFunction)               \
    102   V(SuperPropertyReference)     \
    103   V(SuperCallReference)         \
    104   V(CaseClause)                 \
    105   V(EmptyParentheses)           \
    106   V(GetIterator)                \
    107   V(DoExpression)               \
    108   V(RewritableExpression)
    109 
    110 #define AST_NODE_LIST(V)                        \
    111   DECLARATION_NODE_LIST(V)                      \
    112   STATEMENT_NODE_LIST(V)                        \
    113   EXPRESSION_NODE_LIST(V)
    114 
    115 // Forward declarations
    116 class AstNodeFactory;
    117 class Declaration;
    118 class Module;
    119 class BreakableStatement;
    120 class Expression;
    121 class IterationStatement;
    122 class MaterializedLiteral;
    123 class Statement;
    124 class TypeFeedbackOracle;
    125 
    126 #define DEF_FORWARD_DECLARATION(type) class type;
    127 AST_NODE_LIST(DEF_FORWARD_DECLARATION)
    128 #undef DEF_FORWARD_DECLARATION
    129 
    130 class FeedbackSlotCache {
    131  public:
    132   typedef std::pair<TypeofMode, Variable*> Key;
    133 
    134   explicit FeedbackSlotCache(Zone* zone) : map_(zone) {}
    135 
    136   void Put(TypeofMode typeof_mode, Variable* variable, FeedbackSlot slot) {
    137     Key key = std::make_pair(typeof_mode, variable);
    138     auto entry = std::make_pair(key, slot);
    139     map_.insert(entry);
    140   }
    141 
    142   FeedbackSlot Get(TypeofMode typeof_mode, Variable* variable) const {
    143     Key key = std::make_pair(typeof_mode, variable);
    144     auto iter = map_.find(key);
    145     if (iter != map_.end()) {
    146       return iter->second;
    147     }
    148     return FeedbackSlot();
    149   }
    150 
    151  private:
    152   ZoneMap<Key, FeedbackSlot> map_;
    153 };
    154 
    155 
    156 class AstProperties final BASE_EMBEDDED {
    157  public:
    158   enum Flag {
    159     kNoFlags = 0,
    160     kDontSelfOptimize = 1 << 0,
    161     kMustUseIgnitionTurbo = 1 << 1
    162   };
    163 
    164   typedef base::Flags<Flag> Flags;
    165 
    166   explicit AstProperties(Zone* zone) : node_count_(0), spec_(zone) {}
    167 
    168   Flags& flags() { return flags_; }
    169   Flags flags() const { return flags_; }
    170   int node_count() { return node_count_; }
    171   void add_node_count(int count) { node_count_ += count; }
    172 
    173   const FeedbackVectorSpec* get_spec() const { return &spec_; }
    174   FeedbackVectorSpec* get_spec() { return &spec_; }
    175 
    176  private:
    177   Flags flags_;
    178   int node_count_;
    179   FeedbackVectorSpec spec_;
    180 };
    181 
    182 DEFINE_OPERATORS_FOR_FLAGS(AstProperties::Flags)
    183 
    184 
    185 class AstNode: public ZoneObject {
    186  public:
    187 #define DECLARE_TYPE_ENUM(type) k##type,
    188   enum NodeType : uint8_t { AST_NODE_LIST(DECLARE_TYPE_ENUM) };
    189 #undef DECLARE_TYPE_ENUM
    190 
    191   void* operator new(size_t size, Zone* zone) { return zone->New(size); }
    192 
    193   NodeType node_type() const { return NodeTypeField::decode(bit_field_); }
    194   int position() const { return position_; }
    195 
    196 #ifdef DEBUG
    197   void Print();
    198   void Print(Isolate* isolate);
    199 #endif  // DEBUG
    200 
    201   // Type testing & conversion functions overridden by concrete subclasses.
    202 #define DECLARE_NODE_FUNCTIONS(type) \
    203   V8_INLINE bool Is##type() const;   \
    204   V8_INLINE type* As##type();        \
    205   V8_INLINE const type* As##type() const;
    206   AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
    207 #undef DECLARE_NODE_FUNCTIONS
    208 
    209   BreakableStatement* AsBreakableStatement();
    210   IterationStatement* AsIterationStatement();
    211   MaterializedLiteral* AsMaterializedLiteral();
    212 
    213  private:
    214   // Hidden to prevent accidental usage. It would have to load the
    215   // current zone from the TLS.
    216   void* operator new(size_t size);
    217 
    218   int position_;
    219   class NodeTypeField : public BitField<NodeType, 0, 6> {};
    220 
    221  protected:
    222   uint32_t bit_field_;
    223   static const uint8_t kNextBitFieldIndex = NodeTypeField::kNext;
    224 
    225   AstNode(int position, NodeType type)
    226       : position_(position), bit_field_(NodeTypeField::encode(type)) {}
    227 };
    228 
    229 
    230 class Statement : public AstNode {
    231  public:
    232   bool IsEmpty() { return AsEmptyStatement() != NULL; }
    233   bool IsJump() const;
    234 
    235  protected:
    236   Statement(int position, NodeType type) : AstNode(position, type) {}
    237 
    238   static const uint8_t kNextBitFieldIndex = AstNode::kNextBitFieldIndex;
    239 };
    240 
    241 
    242 class SmallMapList final {
    243  public:
    244   SmallMapList() {}
    245   SmallMapList(int capacity, Zone* zone) : list_(capacity, zone) {}
    246 
    247   void Reserve(int capacity, Zone* zone) { list_.Reserve(capacity, zone); }
    248   void Clear() { list_.Clear(); }
    249   void Sort() { list_.Sort(); }
    250 
    251   bool is_empty() const { return list_.is_empty(); }
    252   int length() const { return list_.length(); }
    253 
    254   void AddMapIfMissing(Handle<Map> map, Zone* zone) {
    255     if (!Map::TryUpdate(map).ToHandle(&map)) return;
    256     for (int i = 0; i < length(); ++i) {
    257       if (at(i).is_identical_to(map)) return;
    258     }
    259     Add(map, zone);
    260   }
    261 
    262   void FilterForPossibleTransitions(Map* root_map) {
    263     for (int i = list_.length() - 1; i >= 0; i--) {
    264       if (at(i)->FindRootMap() != root_map) {
    265         list_.RemoveElement(list_.at(i));
    266       }
    267     }
    268   }
    269 
    270   void Add(Handle<Map> handle, Zone* zone) {
    271     list_.Add(handle.location(), zone);
    272   }
    273 
    274   Handle<Map> at(int i) const {
    275     return Handle<Map>(list_.at(i));
    276   }
    277 
    278   Handle<Map> first() const { return at(0); }
    279   Handle<Map> last() const { return at(length() - 1); }
    280 
    281  private:
    282   // The list stores pointers to Map*, that is Map**, so it's GC safe.
    283   SmallPointerList<Map*> list_;
    284 
    285   DISALLOW_COPY_AND_ASSIGN(SmallMapList);
    286 };
    287 
    288 
    289 class Expression : public AstNode {
    290  public:
    291   enum Context {
    292     // Not assigned a context yet, or else will not be visited during
    293     // code generation.
    294     kUninitialized,
    295     // Evaluated for its side effects.
    296     kEffect,
    297     // Evaluated for its value (and side effects).
    298     kValue,
    299     // Evaluated for control flow (and side effects).
    300     kTest
    301   };
    302 
    303   // Mark this expression as being in tail position.
    304   void MarkTail();
    305 
    306   // True iff the expression is a valid reference expression.
    307   bool IsValidReferenceExpression() const;
    308 
    309   // Helpers for ToBoolean conversion.
    310   bool ToBooleanIsTrue() const;
    311   bool ToBooleanIsFalse() const;
    312 
    313   // Symbols that cannot be parsed as array indices are considered property
    314   // names.  We do not treat symbols that can be array indexes as property
    315   // names because [] for string objects is handled only by keyed ICs.
    316   bool IsPropertyName() const;
    317 
    318   // True iff the expression is a class or function expression without
    319   // a syntactic name.
    320   bool IsAnonymousFunctionDefinition() const;
    321 
    322   // True iff the expression is a literal represented as a smi.
    323   bool IsSmiLiteral() const;
    324 
    325   // True iff the expression is a literal represented as a number.
    326   bool IsNumberLiteral() const;
    327 
    328   // True iff the expression is a string literal.
    329   bool IsStringLiteral() const;
    330 
    331   // True iff the expression is the null literal.
    332   bool IsNullLiteral() const;
    333 
    334   // True if we can prove that the expression is the undefined literal. Note
    335   // that this also checks for loads of the global "undefined" variable.
    336   bool IsUndefinedLiteral() const;
    337 
    338   // True iff the expression is a valid target for an assignment.
    339   bool IsValidReferenceExpressionOrThis() const;
    340 
    341   // TODO(rossberg): this should move to its own AST node eventually.
    342   void RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle);
    343   uint16_t to_boolean_types() const {
    344     return ToBooleanTypesField::decode(bit_field_);
    345   }
    346 
    347   SmallMapList* GetReceiverTypes();
    348   KeyedAccessStoreMode GetStoreMode() const;
    349   IcCheckType GetKeyType() const;
    350   bool IsMonomorphic() const;
    351 
    352   void set_base_id(int id) { base_id_ = id; }
    353   static int num_ids() { return parent_num_ids() + 2; }
    354   BailoutId id() const { return BailoutId(local_id(0)); }
    355   TypeFeedbackId test_id() const { return TypeFeedbackId(local_id(1)); }
    356 
    357  private:
    358   int local_id(int n) const { return base_id() + parent_num_ids() + n; }
    359 
    360   int base_id_;
    361   class ToBooleanTypesField
    362       : public BitField<uint16_t, AstNode::kNextBitFieldIndex, 9> {};
    363 
    364  protected:
    365   Expression(int pos, NodeType type)
    366       : AstNode(pos, type), base_id_(BailoutId::None().ToInt()) {
    367     bit_field_ = ToBooleanTypesField::update(bit_field_, 0);
    368   }
    369 
    370   static int parent_num_ids() { return 0; }
    371   void set_to_boolean_types(uint16_t types) {
    372     bit_field_ = ToBooleanTypesField::update(bit_field_, types);
    373   }
    374   int base_id() const {
    375     DCHECK(!BailoutId(base_id_).IsNone());
    376     return base_id_;
    377   }
    378 
    379   static const uint8_t kNextBitFieldIndex = ToBooleanTypesField::kNext;
    380 };
    381 
    382 
    383 class BreakableStatement : public Statement {
    384  public:
    385   enum BreakableType {
    386     TARGET_FOR_ANONYMOUS,
    387     TARGET_FOR_NAMED_ONLY
    388   };
    389 
    390   // The labels associated with this statement. May be NULL;
    391   // if it is != NULL, guaranteed to contain at least one entry.
    392   ZoneList<const AstRawString*>* labels() const { return labels_; }
    393 
    394   // Code generation
    395   Label* break_target() { return &break_target_; }
    396 
    397   // Testers.
    398   bool is_target_for_anonymous() const {
    399     return BreakableTypeField::decode(bit_field_) == TARGET_FOR_ANONYMOUS;
    400   }
    401 
    402   void set_base_id(int id) { base_id_ = id; }
    403   static int num_ids() { return parent_num_ids() + 2; }
    404   BailoutId EntryId() const { return BailoutId(local_id(0)); }
    405   BailoutId ExitId() const { return BailoutId(local_id(1)); }
    406 
    407  private:
    408   int local_id(int n) const { return base_id() + parent_num_ids() + n; }
    409 
    410   BreakableType breakableType() const {
    411     return BreakableTypeField::decode(bit_field_);
    412   }
    413 
    414   int base_id_;
    415   Label break_target_;
    416   ZoneList<const AstRawString*>* labels_;
    417 
    418   class BreakableTypeField
    419       : public BitField<BreakableType, Statement::kNextBitFieldIndex, 1> {};
    420 
    421  protected:
    422   BreakableStatement(ZoneList<const AstRawString*>* labels,
    423                      BreakableType breakable_type, int position, NodeType type)
    424       : Statement(position, type),
    425         base_id_(BailoutId::None().ToInt()),
    426         labels_(labels) {
    427     DCHECK(labels == NULL || labels->length() > 0);
    428     bit_field_ |= BreakableTypeField::encode(breakable_type);
    429   }
    430   static int parent_num_ids() { return 0; }
    431 
    432   int base_id() const {
    433     DCHECK(!BailoutId(base_id_).IsNone());
    434     return base_id_;
    435   }
    436 
    437   static const uint8_t kNextBitFieldIndex = BreakableTypeField::kNext;
    438 };
    439 
    440 
    441 class Block final : public BreakableStatement {
    442  public:
    443   ZoneList<Statement*>* statements() { return &statements_; }
    444   bool ignore_completion_value() const {
    445     return IgnoreCompletionField::decode(bit_field_);
    446   }
    447 
    448   static int num_ids() { return parent_num_ids() + 1; }
    449   BailoutId DeclsId() const { return BailoutId(local_id(0)); }
    450 
    451   bool IsJump() const {
    452     return !statements_.is_empty() && statements_.last()->IsJump()
    453         && labels() == NULL;  // Good enough as an approximation...
    454   }
    455 
    456   Scope* scope() const { return scope_; }
    457   void set_scope(Scope* scope) { scope_ = scope; }
    458 
    459  private:
    460   friend class AstNodeFactory;
    461 
    462   Block(Zone* zone, ZoneList<const AstRawString*>* labels, int capacity,
    463         bool ignore_completion_value, int pos)
    464       : BreakableStatement(labels, TARGET_FOR_NAMED_ONLY, pos, kBlock),
    465         statements_(capacity, zone),
    466         scope_(NULL) {
    467     bit_field_ |= IgnoreCompletionField::encode(ignore_completion_value);
    468   }
    469   static int parent_num_ids() { return BreakableStatement::num_ids(); }
    470   int local_id(int n) const { return base_id() + parent_num_ids() + n; }
    471 
    472   ZoneList<Statement*> statements_;
    473   Scope* scope_;
    474 
    475   class IgnoreCompletionField
    476       : public BitField<bool, BreakableStatement::kNextBitFieldIndex, 1> {};
    477 };
    478 
    479 
    480 class DoExpression final : public Expression {
    481  public:
    482   Block* block() { return block_; }
    483   void set_block(Block* b) { block_ = b; }
    484   VariableProxy* result() { return result_; }
    485   void set_result(VariableProxy* v) { result_ = v; }
    486   FunctionLiteral* represented_function() { return represented_function_; }
    487   void set_represented_function(FunctionLiteral* f) {
    488     represented_function_ = f;
    489   }
    490   bool IsAnonymousFunctionDefinition() const;
    491 
    492  private:
    493   friend class AstNodeFactory;
    494 
    495   DoExpression(Block* block, VariableProxy* result, int pos)
    496       : Expression(pos, kDoExpression),
    497         block_(block),
    498         result_(result),
    499         represented_function_(nullptr) {
    500     DCHECK_NOT_NULL(block_);
    501     DCHECK_NOT_NULL(result_);
    502   }
    503   static int parent_num_ids() { return Expression::num_ids(); }
    504   int local_id(int n) const { return base_id() + parent_num_ids() + n; }
    505 
    506   Block* block_;
    507   VariableProxy* result_;
    508   FunctionLiteral* represented_function_;
    509 };
    510 
    511 
    512 class Declaration : public AstNode {
    513  public:
    514   typedef ThreadedList<Declaration> List;
    515 
    516   VariableProxy* proxy() const { return proxy_; }
    517   Scope* scope() const { return scope_; }
    518 
    519  protected:
    520   Declaration(VariableProxy* proxy, Scope* scope, int pos, NodeType type)
    521       : AstNode(pos, type), proxy_(proxy), scope_(scope), next_(nullptr) {}
    522 
    523  private:
    524   VariableProxy* proxy_;
    525   // Nested scope from which the declaration originated.
    526   Scope* scope_;
    527   // Declarations list threaded through the declarations.
    528   Declaration** next() { return &next_; }
    529   Declaration* next_;
    530   friend List;
    531 };
    532 
    533 
    534 class VariableDeclaration final : public Declaration {
    535  private:
    536   friend class AstNodeFactory;
    537 
    538   VariableDeclaration(VariableProxy* proxy, Scope* scope, int pos)
    539       : Declaration(proxy, scope, pos, kVariableDeclaration) {}
    540 };
    541 
    542 
    543 class FunctionDeclaration final : public Declaration {
    544  public:
    545   FunctionLiteral* fun() const { return fun_; }
    546   void set_fun(FunctionLiteral* f) { fun_ = f; }
    547 
    548  private:
    549   friend class AstNodeFactory;
    550 
    551   FunctionDeclaration(VariableProxy* proxy, FunctionLiteral* fun, Scope* scope,
    552                       int pos)
    553       : Declaration(proxy, scope, pos, kFunctionDeclaration), fun_(fun) {
    554     DCHECK(fun != NULL);
    555   }
    556 
    557   FunctionLiteral* fun_;
    558 };
    559 
    560 
    561 class IterationStatement : public BreakableStatement {
    562  public:
    563   Statement* body() const { return body_; }
    564   void set_body(Statement* s) { body_ = s; }
    565 
    566   int yield_count() const { return yield_count_; }
    567   int first_yield_id() const { return first_yield_id_; }
    568   void set_yield_count(int yield_count) { yield_count_ = yield_count; }
    569   void set_first_yield_id(int first_yield_id) {
    570     first_yield_id_ = first_yield_id;
    571   }
    572 
    573   static int num_ids() { return parent_num_ids() + 1; }
    574   BailoutId OsrEntryId() const { return BailoutId(local_id(0)); }
    575 
    576   // Code generation
    577   Label* continue_target()  { return &continue_target_; }
    578 
    579  protected:
    580   IterationStatement(ZoneList<const AstRawString*>* labels, int pos,
    581                      NodeType type)
    582       : BreakableStatement(labels, TARGET_FOR_ANONYMOUS, pos, type),
    583         body_(NULL),
    584         yield_count_(0),
    585         first_yield_id_(0) {}
    586   static int parent_num_ids() { return BreakableStatement::num_ids(); }
    587   void Initialize(Statement* body) { body_ = body; }
    588 
    589   static const uint8_t kNextBitFieldIndex =
    590       BreakableStatement::kNextBitFieldIndex;
    591 
    592  private:
    593   int local_id(int n) const { return base_id() + parent_num_ids() + n; }
    594 
    595   Statement* body_;
    596   Label continue_target_;
    597   int yield_count_;
    598   int first_yield_id_;
    599 };
    600 
    601 
    602 class DoWhileStatement final : public IterationStatement {
    603  public:
    604   void Initialize(Expression* cond, Statement* body) {
    605     IterationStatement::Initialize(body);
    606     cond_ = cond;
    607   }
    608 
    609   Expression* cond() const { return cond_; }
    610   void set_cond(Expression* e) { cond_ = e; }
    611 
    612   static int num_ids() { return parent_num_ids() + 2; }
    613   BailoutId ContinueId() const { return BailoutId(local_id(0)); }
    614   BailoutId StackCheckId() const { return BackEdgeId(); }
    615   BailoutId BackEdgeId() const { return BailoutId(local_id(1)); }
    616 
    617  private:
    618   friend class AstNodeFactory;
    619 
    620   DoWhileStatement(ZoneList<const AstRawString*>* labels, int pos)
    621       : IterationStatement(labels, pos, kDoWhileStatement), cond_(NULL) {}
    622   static int parent_num_ids() { return IterationStatement::num_ids(); }
    623   int local_id(int n) const { return base_id() + parent_num_ids() + n; }
    624 
    625   Expression* cond_;
    626 };
    627 
    628 
    629 class WhileStatement final : public IterationStatement {
    630  public:
    631   void Initialize(Expression* cond, Statement* body) {
    632     IterationStatement::Initialize(body);
    633     cond_ = cond;
    634   }
    635 
    636   Expression* cond() const { return cond_; }
    637   void set_cond(Expression* e) { cond_ = e; }
    638 
    639   static int num_ids() { return parent_num_ids() + 1; }
    640   BailoutId ContinueId() const { return EntryId(); }
    641   BailoutId StackCheckId() const { return BodyId(); }
    642   BailoutId BodyId() const { return BailoutId(local_id(0)); }
    643 
    644  private:
    645   friend class AstNodeFactory;
    646 
    647   WhileStatement(ZoneList<const AstRawString*>* labels, int pos)
    648       : IterationStatement(labels, pos, kWhileStatement), cond_(NULL) {}
    649   static int parent_num_ids() { return IterationStatement::num_ids(); }
    650   int local_id(int n) const { return base_id() + parent_num_ids() + n; }
    651 
    652   Expression* cond_;
    653 };
    654 
    655 
    656 class ForStatement final : public IterationStatement {
    657  public:
    658   void Initialize(Statement* init,
    659                   Expression* cond,
    660                   Statement* next,
    661                   Statement* body) {
    662     IterationStatement::Initialize(body);
    663     init_ = init;
    664     cond_ = cond;
    665     next_ = next;
    666   }
    667 
    668   Statement* init() const { return init_; }
    669   Expression* cond() const { return cond_; }
    670   Statement* next() const { return next_; }
    671 
    672   void set_init(Statement* s) { init_ = s; }
    673   void set_cond(Expression* e) { cond_ = e; }
    674   void set_next(Statement* s) { next_ = s; }
    675 
    676   static int num_ids() { return parent_num_ids() + 2; }
    677   BailoutId ContinueId() const { return BailoutId(local_id(0)); }
    678   BailoutId StackCheckId() const { return BodyId(); }
    679   BailoutId BodyId() const { return BailoutId(local_id(1)); }
    680 
    681  private:
    682   friend class AstNodeFactory;
    683 
    684   ForStatement(ZoneList<const AstRawString*>* labels, int pos)
    685       : IterationStatement(labels, pos, kForStatement),
    686         init_(NULL),
    687         cond_(NULL),
    688         next_(NULL) {}
    689   static int parent_num_ids() { return IterationStatement::num_ids(); }
    690   int local_id(int n) const { return base_id() + parent_num_ids() + n; }
    691 
    692   Statement* init_;
    693   Expression* cond_;
    694   Statement* next_;
    695 };
    696 
    697 
    698 class ForEachStatement : public IterationStatement {
    699  public:
    700   enum VisitMode {
    701     ENUMERATE,   // for (each in subject) body;
    702     ITERATE      // for (each of subject) body;
    703   };
    704 
    705   using IterationStatement::Initialize;
    706 
    707   static const char* VisitModeString(VisitMode mode) {
    708     return mode == ITERATE ? "for-of" : "for-in";
    709   }
    710 
    711  protected:
    712   ForEachStatement(ZoneList<const AstRawString*>* labels, int pos,
    713                    NodeType type)
    714       : IterationStatement(labels, pos, type) {}
    715 };
    716 
    717 
    718 class ForInStatement final : public ForEachStatement {
    719  public:
    720   void Initialize(Expression* each, Expression* subject, Statement* body) {
    721     ForEachStatement::Initialize(body);
    722     each_ = each;
    723     subject_ = subject;
    724   }
    725 
    726   Expression* enumerable() const {
    727     return subject();
    728   }
    729 
    730   Expression* each() const { return each_; }
    731   Expression* subject() const { return subject_; }
    732 
    733   void set_each(Expression* e) { each_ = e; }
    734   void set_subject(Expression* e) { subject_ = e; }
    735 
    736   // Type feedback information.
    737   void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
    738                            FeedbackSlotCache* cache);
    739   FeedbackSlot EachFeedbackSlot() const { return each_slot_; }
    740   FeedbackSlot ForInFeedbackSlot() {
    741     DCHECK(!for_in_feedback_slot_.IsInvalid());
    742     return for_in_feedback_slot_;
    743   }
    744 
    745   enum ForInType { FAST_FOR_IN, SLOW_FOR_IN };
    746   ForInType for_in_type() const { return ForInTypeField::decode(bit_field_); }
    747   void set_for_in_type(ForInType type) {
    748     bit_field_ = ForInTypeField::update(bit_field_, type);
    749   }
    750 
    751   static int num_ids() { return parent_num_ids() + 7; }
    752   BailoutId BodyId() const { return BailoutId(local_id(0)); }
    753   BailoutId EnumId() const { return BailoutId(local_id(1)); }
    754   BailoutId ToObjectId() const { return BailoutId(local_id(2)); }
    755   BailoutId PrepareId() const { return BailoutId(local_id(3)); }
    756   BailoutId FilterId() const { return BailoutId(local_id(4)); }
    757   BailoutId AssignmentId() const { return BailoutId(local_id(5)); }
    758   BailoutId IncrementId() const { return BailoutId(local_id(6)); }
    759   BailoutId StackCheckId() const { return BodyId(); }
    760 
    761  private:
    762   friend class AstNodeFactory;
    763 
    764   ForInStatement(ZoneList<const AstRawString*>* labels, int pos)
    765       : ForEachStatement(labels, pos, kForInStatement),
    766         each_(nullptr),
    767         subject_(nullptr) {
    768     bit_field_ = ForInTypeField::update(bit_field_, SLOW_FOR_IN);
    769   }
    770 
    771   static int parent_num_ids() { return ForEachStatement::num_ids(); }
    772   int local_id(int n) const { return base_id() + parent_num_ids() + n; }
    773 
    774   Expression* each_;
    775   Expression* subject_;
    776   FeedbackSlot each_slot_;
    777   FeedbackSlot for_in_feedback_slot_;
    778 
    779   class ForInTypeField
    780       : public BitField<ForInType, ForEachStatement::kNextBitFieldIndex, 1> {};
    781 };
    782 
    783 
    784 class ForOfStatement final : public ForEachStatement {
    785  public:
    786   void Initialize(Statement* body, Variable* iterator,
    787                   Expression* assign_iterator, Expression* next_result,
    788                   Expression* result_done, Expression* assign_each) {
    789     ForEachStatement::Initialize(body);
    790     iterator_ = iterator;
    791     assign_iterator_ = assign_iterator;
    792     next_result_ = next_result;
    793     result_done_ = result_done;
    794     assign_each_ = assign_each;
    795   }
    796 
    797   Variable* iterator() const {
    798     return iterator_;
    799   }
    800 
    801   // iterator = subject[Symbol.iterator]()
    802   Expression* assign_iterator() const {
    803     return assign_iterator_;
    804   }
    805 
    806   // result = iterator.next()  // with type check
    807   Expression* next_result() const {
    808     return next_result_;
    809   }
    810 
    811   // result.done
    812   Expression* result_done() const {
    813     return result_done_;
    814   }
    815 
    816   // each = result.value
    817   Expression* assign_each() const {
    818     return assign_each_;
    819   }
    820 
    821   void set_assign_iterator(Expression* e) { assign_iterator_ = e; }
    822   void set_next_result(Expression* e) { next_result_ = e; }
    823   void set_result_done(Expression* e) { result_done_ = e; }
    824   void set_assign_each(Expression* e) { assign_each_ = e; }
    825 
    826  private:
    827   friend class AstNodeFactory;
    828 
    829   ForOfStatement(ZoneList<const AstRawString*>* labels, int pos)
    830       : ForEachStatement(labels, pos, kForOfStatement),
    831         iterator_(NULL),
    832         assign_iterator_(NULL),
    833         next_result_(NULL),
    834         result_done_(NULL),
    835         assign_each_(NULL) {}
    836 
    837   Variable* iterator_;
    838   Expression* assign_iterator_;
    839   Expression* next_result_;
    840   Expression* result_done_;
    841   Expression* assign_each_;
    842 };
    843 
    844 
    845 class ExpressionStatement final : public Statement {
    846  public:
    847   void set_expression(Expression* e) { expression_ = e; }
    848   Expression* expression() const { return expression_; }
    849   bool IsJump() const { return expression_->IsThrow(); }
    850 
    851  private:
    852   friend class AstNodeFactory;
    853 
    854   ExpressionStatement(Expression* expression, int pos)
    855       : Statement(pos, kExpressionStatement), expression_(expression) {}
    856 
    857   Expression* expression_;
    858 };
    859 
    860 
    861 class JumpStatement : public Statement {
    862  public:
    863   bool IsJump() const { return true; }
    864 
    865  protected:
    866   JumpStatement(int pos, NodeType type) : Statement(pos, type) {}
    867 };
    868 
    869 
    870 class ContinueStatement final : public JumpStatement {
    871  public:
    872   IterationStatement* target() const { return target_; }
    873 
    874  private:
    875   friend class AstNodeFactory;
    876 
    877   ContinueStatement(IterationStatement* target, int pos)
    878       : JumpStatement(pos, kContinueStatement), target_(target) {}
    879 
    880   IterationStatement* target_;
    881 };
    882 
    883 
    884 class BreakStatement final : public JumpStatement {
    885  public:
    886   BreakableStatement* target() const { return target_; }
    887 
    888  private:
    889   friend class AstNodeFactory;
    890 
    891   BreakStatement(BreakableStatement* target, int pos)
    892       : JumpStatement(pos, kBreakStatement), target_(target) {}
    893 
    894   BreakableStatement* target_;
    895 };
    896 
    897 
    898 class ReturnStatement final : public JumpStatement {
    899  public:
    900   enum Type { kNormal, kAsyncReturn };
    901   Expression* expression() const { return expression_; }
    902 
    903   void set_expression(Expression* e) { expression_ = e; }
    904   Type type() const { return TypeField::decode(bit_field_); }
    905   bool is_async_return() const { return type() == kAsyncReturn; }
    906 
    907  private:
    908   friend class AstNodeFactory;
    909 
    910   ReturnStatement(Expression* expression, Type type, int pos)
    911       : JumpStatement(pos, kReturnStatement), expression_(expression) {
    912     bit_field_ |= TypeField::encode(type);
    913   }
    914 
    915   Expression* expression_;
    916 
    917   class TypeField
    918       : public BitField<Type, JumpStatement::kNextBitFieldIndex, 1> {};
    919 };
    920 
    921 
    922 class WithStatement final : public Statement {
    923  public:
    924   Scope* scope() { return scope_; }
    925   Expression* expression() const { return expression_; }
    926   void set_expression(Expression* e) { expression_ = e; }
    927   Statement* statement() const { return statement_; }
    928   void set_statement(Statement* s) { statement_ = s; }
    929 
    930  private:
    931   friend class AstNodeFactory;
    932 
    933   WithStatement(Scope* scope, Expression* expression, Statement* statement,
    934                 int pos)
    935       : Statement(pos, kWithStatement),
    936         scope_(scope),
    937         expression_(expression),
    938         statement_(statement) {}
    939 
    940   Scope* scope_;
    941   Expression* expression_;
    942   Statement* statement_;
    943 };
    944 
    945 
    946 class CaseClause final : public Expression {
    947  public:
    948   bool is_default() const { return label_ == NULL; }
    949   Expression* label() const {
    950     CHECK(!is_default());
    951     return label_;
    952   }
    953   void set_label(Expression* e) { label_ = e; }
    954   Label* body_target() { return &body_target_; }
    955   ZoneList<Statement*>* statements() const { return statements_; }
    956 
    957   static int num_ids() { return parent_num_ids() + 2; }
    958   BailoutId EntryId() const { return BailoutId(local_id(0)); }
    959   TypeFeedbackId CompareId() { return TypeFeedbackId(local_id(1)); }
    960 
    961   AstType* compare_type() { return compare_type_; }
    962   void set_compare_type(AstType* type) { compare_type_ = type; }
    963 
    964   // CaseClause will have both a slot in the feedback vector and the
    965   // TypeFeedbackId to record the type information. TypeFeedbackId is used by
    966   // full codegen and the feedback vector slot is used by interpreter.
    967   void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
    968                            FeedbackSlotCache* cache);
    969 
    970   FeedbackSlot CompareOperationFeedbackSlot() { return feedback_slot_; }
    971 
    972  private:
    973   friend class AstNodeFactory;
    974 
    975   static int parent_num_ids() { return Expression::num_ids(); }
    976   CaseClause(Expression* label, ZoneList<Statement*>* statements, int pos);
    977   int local_id(int n) const { return base_id() + parent_num_ids() + n; }
    978 
    979   Expression* label_;
    980   Label body_target_;
    981   ZoneList<Statement*>* statements_;
    982   AstType* compare_type_;
    983   FeedbackSlot feedback_slot_;
    984 };
    985 
    986 
    987 class SwitchStatement final : public BreakableStatement {
    988  public:
    989   void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) {
    990     tag_ = tag;
    991     cases_ = cases;
    992   }
    993 
    994   Expression* tag() const { return tag_; }
    995   ZoneList<CaseClause*>* cases() const { return cases_; }
    996 
    997   void set_tag(Expression* t) { tag_ = t; }
    998 
    999  private:
   1000   friend class AstNodeFactory;
   1001 
   1002   SwitchStatement(ZoneList<const AstRawString*>* labels, int pos)
   1003       : BreakableStatement(labels, TARGET_FOR_ANONYMOUS, pos, kSwitchStatement),
   1004         tag_(NULL),
   1005         cases_(NULL) {}
   1006 
   1007   Expression* tag_;
   1008   ZoneList<CaseClause*>* cases_;
   1009 };
   1010 
   1011 
   1012 // If-statements always have non-null references to their then- and
   1013 // else-parts. When parsing if-statements with no explicit else-part,
   1014 // the parser implicitly creates an empty statement. Use the
   1015 // HasThenStatement() and HasElseStatement() functions to check if a
   1016 // given if-statement has a then- or an else-part containing code.
   1017 class IfStatement final : public Statement {
   1018  public:
   1019   bool HasThenStatement() const { return !then_statement()->IsEmpty(); }
   1020   bool HasElseStatement() const { return !else_statement()->IsEmpty(); }
   1021 
   1022   Expression* condition() const { return condition_; }
   1023   Statement* then_statement() const { return then_statement_; }
   1024   Statement* else_statement() const { return else_statement_; }
   1025 
   1026   void set_condition(Expression* e) { condition_ = e; }
   1027   void set_then_statement(Statement* s) { then_statement_ = s; }
   1028   void set_else_statement(Statement* s) { else_statement_ = s; }
   1029 
   1030   bool IsJump() const {
   1031     return HasThenStatement() && then_statement()->IsJump()
   1032         && HasElseStatement() && else_statement()->IsJump();
   1033   }
   1034 
   1035   void set_base_id(int id) { base_id_ = id; }
   1036   static int num_ids() { return parent_num_ids() + 3; }
   1037   BailoutId IfId() const { return BailoutId(local_id(0)); }
   1038   BailoutId ThenId() const { return BailoutId(local_id(1)); }
   1039   BailoutId ElseId() const { return BailoutId(local_id(2)); }
   1040 
   1041  private:
   1042   friend class AstNodeFactory;
   1043 
   1044   IfStatement(Expression* condition, Statement* then_statement,
   1045               Statement* else_statement, int pos)
   1046       : Statement(pos, kIfStatement),
   1047         base_id_(BailoutId::None().ToInt()),
   1048         condition_(condition),
   1049         then_statement_(then_statement),
   1050         else_statement_(else_statement) {}
   1051 
   1052   static int parent_num_ids() { return 0; }
   1053   int base_id() const {
   1054     DCHECK(!BailoutId(base_id_).IsNone());
   1055     return base_id_;
   1056   }
   1057   int local_id(int n) const { return base_id() + parent_num_ids() + n; }
   1058 
   1059   int base_id_;
   1060   Expression* condition_;
   1061   Statement* then_statement_;
   1062   Statement* else_statement_;
   1063 };
   1064 
   1065 
   1066 class TryStatement : public Statement {
   1067  public:
   1068   Block* try_block() const { return try_block_; }
   1069   void set_try_block(Block* b) { try_block_ = b; }
   1070 
   1071   // Prediction of whether exceptions thrown into the handler for this try block
   1072   // will be caught.
   1073   //
   1074   // This is set in ast-numbering and later compiled into the code's handler
   1075   // table.  The runtime uses this information to implement a feature that
   1076   // notifies the debugger when an uncaught exception is thrown, _before_ the
   1077   // exception propagates to the top.
   1078   //
   1079   // Since it's generally undecidable whether an exception will be caught, our
   1080   // prediction is only an approximation.
   1081   HandlerTable::CatchPrediction catch_prediction() const {
   1082     return catch_prediction_;
   1083   }
   1084   void set_catch_prediction(HandlerTable::CatchPrediction prediction) {
   1085     catch_prediction_ = prediction;
   1086   }
   1087 
   1088  protected:
   1089   TryStatement(Block* try_block, int pos, NodeType type)
   1090       : Statement(pos, type),
   1091         catch_prediction_(HandlerTable::UNCAUGHT),
   1092         try_block_(try_block) {}
   1093 
   1094   HandlerTable::CatchPrediction catch_prediction_;
   1095 
   1096  private:
   1097   Block* try_block_;
   1098 };
   1099 
   1100 
   1101 class TryCatchStatement final : public TryStatement {
   1102  public:
   1103   Scope* scope() { return scope_; }
   1104   Variable* variable() { return variable_; }
   1105   Block* catch_block() const { return catch_block_; }
   1106   void set_catch_block(Block* b) { catch_block_ = b; }
   1107 
   1108   // The clear_pending_message flag indicates whether or not to clear the
   1109   // isolate's pending exception message before executing the catch_block.  In
   1110   // the normal use case, this flag is always on because the message object
   1111   // is not needed anymore when entering the catch block and should not be kept
   1112   // alive.
   1113   // The use case where the flag is off is when the catch block is guaranteed to
   1114   // rethrow the caught exception (using %ReThrow), which reuses the pending
   1115   // message instead of generating a new one.
   1116   // (When the catch block doesn't rethrow but is guaranteed to perform an
   1117   // ordinary throw, not clearing the old message is safe but not very useful.)
   1118   bool clear_pending_message() const {
   1119     return catch_prediction_ != HandlerTable::UNCAUGHT;
   1120   }
   1121 
   1122  private:
   1123   friend class AstNodeFactory;
   1124 
   1125   TryCatchStatement(Block* try_block, Scope* scope, Variable* variable,
   1126                     Block* catch_block,
   1127                     HandlerTable::CatchPrediction catch_prediction, int pos)
   1128       : TryStatement(try_block, pos, kTryCatchStatement),
   1129         scope_(scope),
   1130         variable_(variable),
   1131         catch_block_(catch_block) {
   1132     catch_prediction_ = catch_prediction;
   1133   }
   1134 
   1135   Scope* scope_;
   1136   Variable* variable_;
   1137   Block* catch_block_;
   1138 };
   1139 
   1140 
   1141 class TryFinallyStatement final : public TryStatement {
   1142  public:
   1143   Block* finally_block() const { return finally_block_; }
   1144   void set_finally_block(Block* b) { finally_block_ = b; }
   1145 
   1146  private:
   1147   friend class AstNodeFactory;
   1148 
   1149   TryFinallyStatement(Block* try_block, Block* finally_block, int pos)
   1150       : TryStatement(try_block, pos, kTryFinallyStatement),
   1151         finally_block_(finally_block) {}
   1152 
   1153   Block* finally_block_;
   1154 };
   1155 
   1156 
   1157 class DebuggerStatement final : public Statement {
   1158  private:
   1159   friend class AstNodeFactory;
   1160 
   1161   explicit DebuggerStatement(int pos) : Statement(pos, kDebuggerStatement) {}
   1162 };
   1163 
   1164 
   1165 class EmptyStatement final : public Statement {
   1166  private:
   1167   friend class AstNodeFactory;
   1168   explicit EmptyStatement(int pos) : Statement(pos, kEmptyStatement) {}
   1169 };
   1170 
   1171 
   1172 // Delegates to another statement, which may be overwritten.
   1173 // This was introduced to implement ES2015 Annex B3.3 for conditionally making
   1174 // sloppy-mode block-scoped functions have a var binding, which is changed
   1175 // from one statement to another during parsing.
   1176 class SloppyBlockFunctionStatement final : public Statement {
   1177  public:
   1178   Statement* statement() const { return statement_; }
   1179   void set_statement(Statement* statement) { statement_ = statement; }
   1180 
   1181  private:
   1182   friend class AstNodeFactory;
   1183 
   1184   explicit SloppyBlockFunctionStatement(Statement* statement)
   1185       : Statement(kNoSourcePosition, kSloppyBlockFunctionStatement),
   1186         statement_(statement) {}
   1187 
   1188   Statement* statement_;
   1189 };
   1190 
   1191 
   1192 class Literal final : public Expression {
   1193  public:
   1194   // Returns true if literal represents a property name (i.e. cannot be parsed
   1195   // as array indices).
   1196   bool IsPropertyName() const { return value_->IsPropertyName(); }
   1197 
   1198   Handle<String> AsPropertyName() {
   1199     DCHECK(IsPropertyName());
   1200     return Handle<String>::cast(value());
   1201   }
   1202 
   1203   const AstRawString* AsRawPropertyName() {
   1204     DCHECK(IsPropertyName());
   1205     return value_->AsString();
   1206   }
   1207 
   1208   bool ToBooleanIsTrue() const { return raw_value()->BooleanValue(); }
   1209   bool ToBooleanIsFalse() const { return !raw_value()->BooleanValue(); }
   1210 
   1211   Handle<Object> value() const { return value_->value(); }
   1212   const AstValue* raw_value() const { return value_; }
   1213 
   1214   // Support for using Literal as a HashMap key. NOTE: Currently, this works
   1215   // only for string and number literals!
   1216   uint32_t Hash();
   1217   static bool Match(void* literal1, void* literal2);
   1218 
   1219   static int num_ids() { return parent_num_ids() + 1; }
   1220   TypeFeedbackId LiteralFeedbackId() const {
   1221     return TypeFeedbackId(local_id(0));
   1222   }
   1223 
   1224  private:
   1225   friend class AstNodeFactory;
   1226 
   1227   Literal(const AstValue* value, int position)
   1228       : Expression(position, kLiteral), value_(value) {}
   1229 
   1230   static int parent_num_ids() { return Expression::num_ids(); }
   1231   int local_id(int n) const { return base_id() + parent_num_ids() + n; }
   1232 
   1233   const AstValue* value_;
   1234 };
   1235 
   1236 // Base class for literals that need space in the type feedback vector.
   1237 class MaterializedLiteral : public Expression {
   1238  public:
   1239   int depth() const {
   1240     // only callable after initialization.
   1241     DCHECK(depth_ >= 1);
   1242     return depth_;
   1243   }
   1244 
   1245   void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
   1246                            FeedbackSlotCache* cache) {
   1247     literal_slot_ = spec->AddLiteralSlot();
   1248   }
   1249 
   1250   FeedbackSlot literal_slot() const { return literal_slot_; }
   1251 
   1252  private:
   1253   int depth_ : 31;
   1254   FeedbackSlot literal_slot_;
   1255 
   1256   class IsSimpleField
   1257       : public BitField<bool, Expression::kNextBitFieldIndex, 1> {};
   1258 
   1259  protected:
   1260   MaterializedLiteral(int pos, NodeType type)
   1261       : Expression(pos, type), depth_(0) {
   1262     bit_field_ |= IsSimpleField::encode(false);
   1263   }
   1264 
   1265   // A materialized literal is simple if the values consist of only
   1266   // constants and simple object and array literals.
   1267   bool is_simple() const { return IsSimpleField::decode(bit_field_); }
   1268   void set_is_simple(bool is_simple) {
   1269     bit_field_ = IsSimpleField::update(bit_field_, is_simple);
   1270   }
   1271   friend class CompileTimeValue;
   1272 
   1273   void set_depth(int depth) {
   1274     DCHECK_LE(1, depth);
   1275     depth_ = depth;
   1276   }
   1277 
   1278   // Populate the depth field and any flags the literal has.
   1279   void InitDepthAndFlags();
   1280 
   1281   // Populate the constant properties/elements fixed array.
   1282   void BuildConstants(Isolate* isolate);
   1283   friend class ArrayLiteral;
   1284   friend class ObjectLiteral;
   1285 
   1286   // If the expression is a literal, return the literal value;
   1287   // if the expression is a materialized literal and is simple return a
   1288   // compile time value as encoded by CompileTimeValue::GetValue().
   1289   // Otherwise, return undefined literal as the placeholder
   1290   // in the object literal boilerplate.
   1291   Handle<Object> GetBoilerplateValue(Expression* expression, Isolate* isolate);
   1292 
   1293   static const uint8_t kNextBitFieldIndex = IsSimpleField::kNext;
   1294 };
   1295 
   1296 // Common supertype for ObjectLiteralProperty and ClassLiteralProperty
   1297 class LiteralProperty : public ZoneObject {
   1298  public:
   1299   Expression* key() const { return key_; }
   1300   Expression* value() const { return value_; }
   1301   void set_key(Expression* e) { key_ = e; }
   1302   void set_value(Expression* e) { value_ = e; }
   1303 
   1304   bool is_computed_name() const { return is_computed_name_; }
   1305 
   1306   FeedbackSlot GetSlot(int offset = 0) const {
   1307     DCHECK_LT(offset, static_cast<int>(arraysize(slots_)));
   1308     return slots_[offset];
   1309   }
   1310 
   1311   FeedbackSlot GetStoreDataPropertySlot() const;
   1312 
   1313   void SetSlot(FeedbackSlot slot, int offset = 0) {
   1314     DCHECK_LT(offset, static_cast<int>(arraysize(slots_)));
   1315     slots_[offset] = slot;
   1316   }
   1317 
   1318   void SetStoreDataPropertySlot(FeedbackSlot slot);
   1319 
   1320   bool NeedsSetFunctionName() const;
   1321 
   1322  protected:
   1323   LiteralProperty(Expression* key, Expression* value, bool is_computed_name)
   1324       : key_(key), value_(value), is_computed_name_(is_computed_name) {}
   1325 
   1326   Expression* key_;
   1327   Expression* value_;
   1328   FeedbackSlot slots_[2];
   1329   bool is_computed_name_;
   1330 };
   1331 
   1332 // Property is used for passing information
   1333 // about an object literal's properties from the parser
   1334 // to the code generator.
   1335 class ObjectLiteralProperty final : public LiteralProperty {
   1336  public:
   1337   enum Kind : uint8_t {
   1338     CONSTANT,              // Property with constant value (compile time).
   1339     COMPUTED,              // Property with computed value (execution time).
   1340     MATERIALIZED_LITERAL,  // Property value is a materialized literal.
   1341     GETTER,
   1342     SETTER,     // Property is an accessor function.
   1343     PROTOTYPE,  // Property is __proto__.
   1344     SPREAD
   1345   };
   1346 
   1347   Kind kind() const { return kind_; }
   1348 
   1349   // Type feedback information.
   1350   bool IsMonomorphic() const { return !receiver_type_.is_null(); }
   1351   Handle<Map> GetReceiverType() const { return receiver_type_; }
   1352 
   1353   bool IsCompileTimeValue() const;
   1354 
   1355   void set_emit_store(bool emit_store);
   1356   bool emit_store() const;
   1357 
   1358   void set_receiver_type(Handle<Map> map) { receiver_type_ = map; }
   1359 
   1360  private:
   1361   friend class AstNodeFactory;
   1362 
   1363   ObjectLiteralProperty(Expression* key, Expression* value, Kind kind,
   1364                         bool is_computed_name);
   1365   ObjectLiteralProperty(AstValueFactory* ast_value_factory, Expression* key,
   1366                         Expression* value, bool is_computed_name);
   1367 
   1368   Kind kind_;
   1369   bool emit_store_;
   1370   Handle<Map> receiver_type_;
   1371 };
   1372 
   1373 
   1374 // An object literal has a boilerplate object that is used
   1375 // for minimizing the work when constructing it at runtime.
   1376 class ObjectLiteral final : public MaterializedLiteral {
   1377  public:
   1378   typedef ObjectLiteralProperty Property;
   1379 
   1380   Handle<BoilerplateDescription> constant_properties() const {
   1381     DCHECK(!constant_properties_.is_null());
   1382     return constant_properties_;
   1383   }
   1384   int properties_count() const { return boilerplate_properties_; }
   1385   ZoneList<Property*>* properties() const { return properties_; }
   1386   bool fast_elements() const { return FastElementsField::decode(bit_field_); }
   1387   bool may_store_doubles() const {
   1388     return MayStoreDoublesField::decode(bit_field_);
   1389   }
   1390   bool has_elements() const { return HasElementsField::decode(bit_field_); }
   1391   bool has_shallow_properties() const {
   1392     return depth() == 1 && !has_elements() && !may_store_doubles();
   1393   }
   1394   bool has_rest_property() const {
   1395     return HasRestPropertyField::decode(bit_field_);
   1396   }
   1397 
   1398   // Decide if a property should be in the object boilerplate.
   1399   static bool IsBoilerplateProperty(Property* property);
   1400 
   1401   // Populate the depth field and flags.
   1402   void InitDepthAndFlags();
   1403 
   1404   // Get the constant properties fixed array, populating it if necessary.
   1405   Handle<BoilerplateDescription> GetOrBuildConstantProperties(
   1406       Isolate* isolate) {
   1407     if (constant_properties_.is_null()) {
   1408       BuildConstantProperties(isolate);
   1409     }
   1410     return constant_properties();
   1411   }
   1412 
   1413   // Populate the constant properties fixed array.
   1414   void BuildConstantProperties(Isolate* isolate);
   1415 
   1416   // Mark all computed expressions that are bound to a key that
   1417   // is shadowed by a later occurrence of the same key. For the
   1418   // marked expressions, no store code is emitted.
   1419   void CalculateEmitStore(Zone* zone);
   1420 
   1421   // Determines whether the {FastCloneShallowObject} builtin can be used.
   1422   bool IsFastCloningSupported() const;
   1423 
   1424   // Assemble bitfield of flags for the CreateObjectLiteral helper.
   1425   int ComputeFlags(bool disable_mementos = false) const {
   1426     int flags = fast_elements() ? kFastElements : kNoFlags;
   1427     if (has_shallow_properties()) {
   1428       flags |= kShallowProperties;
   1429     }
   1430     if (disable_mementos) {
   1431       flags |= kDisableMementos;
   1432     }
   1433     return flags;
   1434   }
   1435 
   1436   enum Flags {
   1437     kNoFlags = 0,
   1438     kFastElements = 1,
   1439     kShallowProperties = 1 << 1,
   1440     kDisableMementos = 1 << 2,
   1441     kHasRestProperty = 1 << 3,
   1442   };
   1443 
   1444   struct Accessors: public ZoneObject {
   1445     Accessors() : getter(NULL), setter(NULL), bailout_id(BailoutId::None()) {}
   1446     ObjectLiteralProperty* getter;
   1447     ObjectLiteralProperty* setter;
   1448     BailoutId bailout_id;
   1449   };
   1450 
   1451   BailoutId CreateLiteralId() const { return BailoutId(local_id(0)); }
   1452 
   1453   // Return an AST id for a property that is used in simulate instructions.
   1454   BailoutId GetIdForPropertySet(int i) { return BailoutId(local_id(i + 1)); }
   1455 
   1456   // Unlike other AST nodes, this number of bailout IDs allocated for an
   1457   // ObjectLiteral can vary, so num_ids() is not a static method.
   1458   int num_ids() const { return parent_num_ids() + 1 + properties()->length(); }
   1459 
   1460   // Object literals need one feedback slot for each non-trivial value, as well
   1461   // as some slots for home objects.
   1462   void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
   1463                            FeedbackSlotCache* cache);
   1464 
   1465  private:
   1466   friend class AstNodeFactory;
   1467 
   1468   ObjectLiteral(ZoneList<Property*>* properties,
   1469                 uint32_t boilerplate_properties, int pos,
   1470                 bool has_rest_property)
   1471       : MaterializedLiteral(pos, kObjectLiteral),
   1472         boilerplate_properties_(boilerplate_properties),
   1473         properties_(properties) {
   1474     bit_field_ |= FastElementsField::encode(false) |
   1475                   HasElementsField::encode(false) |
   1476                   MayStoreDoublesField::encode(false) |
   1477                   HasRestPropertyField::encode(has_rest_property);
   1478   }
   1479 
   1480   static int parent_num_ids() { return MaterializedLiteral::num_ids(); }
   1481   int local_id(int n) const { return base_id() + parent_num_ids() + n; }
   1482 
   1483   uint32_t boilerplate_properties_;
   1484   Handle<BoilerplateDescription> constant_properties_;
   1485   ZoneList<Property*>* properties_;
   1486 
   1487   class FastElementsField
   1488       : public BitField<bool, MaterializedLiteral::kNextBitFieldIndex, 1> {};
   1489   class HasElementsField : public BitField<bool, FastElementsField::kNext, 1> {
   1490   };
   1491   class MayStoreDoublesField
   1492       : public BitField<bool, HasElementsField::kNext, 1> {};
   1493   class HasRestPropertyField
   1494       : public BitField<bool, MayStoreDoublesField::kNext, 1> {};
   1495 };
   1496 
   1497 
   1498 // A map from property names to getter/setter pairs allocated in the zone.
   1499 class AccessorTable
   1500     : public base::TemplateHashMap<Literal, ObjectLiteral::Accessors,
   1501                                    bool (*)(void*, void*),
   1502                                    ZoneAllocationPolicy> {
   1503  public:
   1504   explicit AccessorTable(Zone* zone)
   1505       : base::TemplateHashMap<Literal, ObjectLiteral::Accessors,
   1506                               bool (*)(void*, void*), ZoneAllocationPolicy>(
   1507             Literal::Match, ZoneAllocationPolicy(zone)),
   1508         zone_(zone) {}
   1509 
   1510   Iterator lookup(Literal* literal) {
   1511     Iterator it = find(literal, true, ZoneAllocationPolicy(zone_));
   1512     if (it->second == NULL) it->second = new (zone_) ObjectLiteral::Accessors();
   1513     return it;
   1514   }
   1515 
   1516  private:
   1517   Zone* zone_;
   1518 };
   1519 
   1520 
   1521 // Node for capturing a regexp literal.
   1522 class RegExpLiteral final : public MaterializedLiteral {
   1523  public:
   1524   Handle<String> pattern() const { return pattern_->string(); }
   1525   const AstRawString* raw_pattern() const { return pattern_; }
   1526   int flags() const { return flags_; }
   1527 
   1528  private:
   1529   friend class AstNodeFactory;
   1530 
   1531   RegExpLiteral(const AstRawString* pattern, int flags, int pos)
   1532       : MaterializedLiteral(pos, kRegExpLiteral),
   1533         flags_(flags),
   1534         pattern_(pattern) {
   1535     set_depth(1);
   1536   }
   1537 
   1538   int const flags_;
   1539   const AstRawString* const pattern_;
   1540 };
   1541 
   1542 
   1543 // An array literal has a literals object that is used
   1544 // for minimizing the work when constructing it at runtime.
   1545 class ArrayLiteral final : public MaterializedLiteral {
   1546  public:
   1547   Handle<ConstantElementsPair> constant_elements() const {
   1548     return constant_elements_;
   1549   }
   1550   ElementsKind constant_elements_kind() const;
   1551 
   1552   ZoneList<Expression*>* values() const { return values_; }
   1553 
   1554   BailoutId CreateLiteralId() const { return BailoutId(local_id(0)); }
   1555 
   1556   // Return an AST id for an element that is used in simulate instructions.
   1557   BailoutId GetIdForElement(int i) { return BailoutId(local_id(i + 1)); }
   1558 
   1559   // Unlike other AST nodes, this number of bailout IDs allocated for an
   1560   // ArrayLiteral can vary, so num_ids() is not a static method.
   1561   int num_ids() const { return parent_num_ids() + 1 + values()->length(); }
   1562 
   1563   // Populate the depth field and flags.
   1564   void InitDepthAndFlags();
   1565 
   1566   // Get the constant elements fixed array, populating it if necessary.
   1567   Handle<ConstantElementsPair> GetOrBuildConstantElements(Isolate* isolate) {
   1568     if (constant_elements_.is_null()) {
   1569       BuildConstantElements(isolate);
   1570     }
   1571     return constant_elements();
   1572   }
   1573 
   1574   // Populate the constant elements fixed array.
   1575   void BuildConstantElements(Isolate* isolate);
   1576 
   1577   // Determines whether the {FastCloneShallowArray} builtin can be used.
   1578   bool IsFastCloningSupported() const;
   1579 
   1580   // Assemble bitfield of flags for the CreateArrayLiteral helper.
   1581   int ComputeFlags(bool disable_mementos = false) const {
   1582     int flags = depth() == 1 ? kShallowElements : kNoFlags;
   1583     if (disable_mementos) {
   1584       flags |= kDisableMementos;
   1585     }
   1586     return flags;
   1587   }
   1588 
   1589   // Provide a mechanism for iterating through values to rewrite spreads.
   1590   ZoneList<Expression*>::iterator FirstSpread() const {
   1591     return (first_spread_index_ >= 0) ? values_->begin() + first_spread_index_
   1592                                       : values_->end();
   1593   }
   1594   ZoneList<Expression*>::iterator EndValue() const { return values_->end(); }
   1595 
   1596   // Rewind an array literal omitting everything from the first spread on.
   1597   void RewindSpreads();
   1598 
   1599   enum Flags {
   1600     kNoFlags = 0,
   1601     kShallowElements = 1,
   1602     kDisableMementos = 1 << 1
   1603   };
   1604 
   1605   void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
   1606                            FeedbackSlotCache* cache);
   1607   FeedbackSlot LiteralFeedbackSlot() const { return literal_slot_; }
   1608 
   1609  private:
   1610   friend class AstNodeFactory;
   1611 
   1612   ArrayLiteral(ZoneList<Expression*>* values, int first_spread_index, int pos)
   1613       : MaterializedLiteral(pos, kArrayLiteral),
   1614         first_spread_index_(first_spread_index),
   1615         values_(values) {}
   1616 
   1617   static int parent_num_ids() { return MaterializedLiteral::num_ids(); }
   1618   int local_id(int n) const { return base_id() + parent_num_ids() + n; }
   1619 
   1620   int first_spread_index_;
   1621   FeedbackSlot literal_slot_;
   1622   Handle<ConstantElementsPair> constant_elements_;
   1623   ZoneList<Expression*>* values_;
   1624 };
   1625 
   1626 
   1627 class VariableProxy final : public Expression {
   1628  public:
   1629   bool IsValidReferenceExpression() const {
   1630     return !is_this() && !is_new_target();
   1631   }
   1632 
   1633   Handle<String> name() const { return raw_name()->string(); }
   1634   const AstRawString* raw_name() const {
   1635     return is_resolved() ? var_->raw_name() : raw_name_;
   1636   }
   1637 
   1638   Variable* var() const {
   1639     DCHECK(is_resolved());
   1640     return var_;
   1641   }
   1642   void set_var(Variable* v) {
   1643     DCHECK(!is_resolved());
   1644     DCHECK_NOT_NULL(v);
   1645     var_ = v;
   1646   }
   1647 
   1648   bool is_this() const { return IsThisField::decode(bit_field_); }
   1649 
   1650   bool is_assigned() const { return IsAssignedField::decode(bit_field_); }
   1651   void set_is_assigned() {
   1652     bit_field_ = IsAssignedField::update(bit_field_, true);
   1653     if (is_resolved()) {
   1654       var()->set_maybe_assigned();
   1655     }
   1656   }
   1657 
   1658   bool is_resolved() const { return IsResolvedField::decode(bit_field_); }
   1659   void set_is_resolved() {
   1660     bit_field_ = IsResolvedField::update(bit_field_, true);
   1661   }
   1662 
   1663   bool is_new_target() const { return IsNewTargetField::decode(bit_field_); }
   1664   void set_is_new_target() {
   1665     bit_field_ = IsNewTargetField::update(bit_field_, true);
   1666   }
   1667 
   1668   HoleCheckMode hole_check_mode() const {
   1669     return HoleCheckModeField::decode(bit_field_);
   1670   }
   1671   void set_needs_hole_check() {
   1672     bit_field_ =
   1673         HoleCheckModeField::update(bit_field_, HoleCheckMode::kRequired);
   1674   }
   1675 
   1676   // Bind this proxy to the variable var.
   1677   void BindTo(Variable* var);
   1678 
   1679   bool UsesVariableFeedbackSlot() const {
   1680     return var()->IsUnallocated() || var()->IsLookupSlot();
   1681   }
   1682 
   1683   void AssignFeedbackSlots(FeedbackVectorSpec* spec, TypeofMode typeof_mode,
   1684                            FeedbackSlotCache* cache);
   1685 
   1686   FeedbackSlot VariableFeedbackSlot() { return variable_feedback_slot_; }
   1687 
   1688   static int num_ids() { return parent_num_ids() + 1; }
   1689   BailoutId BeforeId() const { return BailoutId(local_id(0)); }
   1690   void set_next_unresolved(VariableProxy* next) { next_unresolved_ = next; }
   1691   VariableProxy* next_unresolved() { return next_unresolved_; }
   1692 
   1693  private:
   1694   friend class AstNodeFactory;
   1695 
   1696   VariableProxy(Variable* var, int start_position);
   1697   VariableProxy(const AstRawString* name, VariableKind variable_kind,
   1698                 int start_position);
   1699   explicit VariableProxy(const VariableProxy* copy_from);
   1700 
   1701   static int parent_num_ids() { return Expression::num_ids(); }
   1702   int local_id(int n) const { return base_id() + parent_num_ids() + n; }
   1703 
   1704   class IsThisField : public BitField<bool, Expression::kNextBitFieldIndex, 1> {
   1705   };
   1706   class IsAssignedField : public BitField<bool, IsThisField::kNext, 1> {};
   1707   class IsResolvedField : public BitField<bool, IsAssignedField::kNext, 1> {};
   1708   class IsNewTargetField : public BitField<bool, IsResolvedField::kNext, 1> {};
   1709   class HoleCheckModeField
   1710       : public BitField<HoleCheckMode, IsNewTargetField::kNext, 1> {};
   1711 
   1712   FeedbackSlot variable_feedback_slot_;
   1713   union {
   1714     const AstRawString* raw_name_;  // if !is_resolved_
   1715     Variable* var_;                 // if is_resolved_
   1716   };
   1717   VariableProxy* next_unresolved_;
   1718 };
   1719 
   1720 
   1721 // Left-hand side can only be a property, a global or a (parameter or local)
   1722 // slot.
   1723 enum LhsKind {
   1724   VARIABLE,
   1725   NAMED_PROPERTY,
   1726   KEYED_PROPERTY,
   1727   NAMED_SUPER_PROPERTY,
   1728   KEYED_SUPER_PROPERTY
   1729 };
   1730 
   1731 
   1732 class Property final : public Expression {
   1733  public:
   1734   bool IsValidReferenceExpression() const { return true; }
   1735 
   1736   Expression* obj() const { return obj_; }
   1737   Expression* key() const { return key_; }
   1738 
   1739   void set_obj(Expression* e) { obj_ = e; }
   1740   void set_key(Expression* e) { key_ = e; }
   1741 
   1742   static int num_ids() { return parent_num_ids() + 1; }
   1743   BailoutId LoadId() const { return BailoutId(local_id(0)); }
   1744 
   1745   bool IsStringAccess() const {
   1746     return IsStringAccessField::decode(bit_field_);
   1747   }
   1748 
   1749   // Type feedback information.
   1750   bool IsMonomorphic() const { return receiver_types_.length() == 1; }
   1751   SmallMapList* GetReceiverTypes() { return &receiver_types_; }
   1752   KeyedAccessStoreMode GetStoreMode() const { return STANDARD_STORE; }
   1753   IcCheckType GetKeyType() const { return KeyTypeField::decode(bit_field_); }
   1754   bool IsUninitialized() const {
   1755     return !is_for_call() && HasNoTypeInformation();
   1756   }
   1757   bool HasNoTypeInformation() const {
   1758     return GetInlineCacheState() == UNINITIALIZED;
   1759   }
   1760   InlineCacheState GetInlineCacheState() const {
   1761     return InlineCacheStateField::decode(bit_field_);
   1762   }
   1763   void set_is_string_access(bool b) {
   1764     bit_field_ = IsStringAccessField::update(bit_field_, b);
   1765   }
   1766   void set_key_type(IcCheckType key_type) {
   1767     bit_field_ = KeyTypeField::update(bit_field_, key_type);
   1768   }
   1769   void set_inline_cache_state(InlineCacheState state) {
   1770     bit_field_ = InlineCacheStateField::update(bit_field_, state);
   1771   }
   1772   void mark_for_call() {
   1773     bit_field_ = IsForCallField::update(bit_field_, true);
   1774   }
   1775   bool is_for_call() const { return IsForCallField::decode(bit_field_); }
   1776 
   1777   bool IsSuperAccess() { return obj()->IsSuperPropertyReference(); }
   1778 
   1779   void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
   1780                            FeedbackSlotCache* cache) {
   1781     if (key()->IsPropertyName()) {
   1782       property_feedback_slot_ = spec->AddLoadICSlot();
   1783     } else {
   1784       property_feedback_slot_ = spec->AddKeyedLoadICSlot();
   1785     }
   1786   }
   1787 
   1788   FeedbackSlot PropertyFeedbackSlot() const { return property_feedback_slot_; }
   1789 
   1790   // Returns the properties assign type.
   1791   static LhsKind GetAssignType(Property* property) {
   1792     if (property == NULL) return VARIABLE;
   1793     bool super_access = property->IsSuperAccess();
   1794     return (property->key()->IsPropertyName())
   1795                ? (super_access ? NAMED_SUPER_PROPERTY : NAMED_PROPERTY)
   1796                : (super_access ? KEYED_SUPER_PROPERTY : KEYED_PROPERTY);
   1797   }
   1798 
   1799  private:
   1800   friend class AstNodeFactory;
   1801 
   1802   Property(Expression* obj, Expression* key, int pos)
   1803       : Expression(pos, kProperty), obj_(obj), key_(key) {
   1804     bit_field_ |= IsForCallField::encode(false) |
   1805                   IsStringAccessField::encode(false) |
   1806                   InlineCacheStateField::encode(UNINITIALIZED);
   1807   }
   1808 
   1809   static int parent_num_ids() { return Expression::num_ids(); }
   1810   int local_id(int n) const { return base_id() + parent_num_ids() + n; }
   1811 
   1812   class IsForCallField
   1813       : public BitField<bool, Expression::kNextBitFieldIndex, 1> {};
   1814   class IsStringAccessField : public BitField<bool, IsForCallField::kNext, 1> {
   1815   };
   1816   class KeyTypeField
   1817       : public BitField<IcCheckType, IsStringAccessField::kNext, 1> {};
   1818   class InlineCacheStateField
   1819       : public BitField<InlineCacheState, KeyTypeField::kNext, 4> {};
   1820 
   1821   FeedbackSlot property_feedback_slot_;
   1822   Expression* obj_;
   1823   Expression* key_;
   1824   SmallMapList receiver_types_;
   1825 };
   1826 
   1827 
   1828 class Call final : public Expression {
   1829  public:
   1830   Expression* expression() const { return expression_; }
   1831   ZoneList<Expression*>* arguments() const { return arguments_; }
   1832 
   1833   void set_expression(Expression* e) { expression_ = e; }
   1834 
   1835   // Type feedback information.
   1836   void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
   1837                            FeedbackSlotCache* cache);
   1838 
   1839   FeedbackSlot CallFeedbackICSlot() const { return ic_slot_; }
   1840 
   1841   SmallMapList* GetReceiverTypes() {
   1842     if (expression()->IsProperty()) {
   1843       return expression()->AsProperty()->GetReceiverTypes();
   1844     }
   1845     return nullptr;
   1846   }
   1847 
   1848   bool IsMonomorphic() const {
   1849     if (expression()->IsProperty()) {
   1850       return expression()->AsProperty()->IsMonomorphic();
   1851     }
   1852     return !target_.is_null();
   1853   }
   1854 
   1855   Handle<JSFunction> target() { return target_; }
   1856 
   1857   Handle<AllocationSite> allocation_site() { return allocation_site_; }
   1858 
   1859   void SetKnownGlobalTarget(Handle<JSFunction> target) {
   1860     target_ = target;
   1861     set_is_uninitialized(false);
   1862   }
   1863   void set_target(Handle<JSFunction> target) { target_ = target; }
   1864   void set_allocation_site(Handle<AllocationSite> site) {
   1865     allocation_site_ = site;
   1866   }
   1867 
   1868   static int num_ids() { return parent_num_ids() + 2; }
   1869   BailoutId ReturnId() const { return BailoutId(local_id(0)); }
   1870   BailoutId CallId() const { return BailoutId(local_id(1)); }
   1871 
   1872   bool is_uninitialized() const {
   1873     return IsUninitializedField::decode(bit_field_);
   1874   }
   1875   void set_is_uninitialized(bool b) {
   1876     bit_field_ = IsUninitializedField::update(bit_field_, b);
   1877   }
   1878 
   1879   bool is_possibly_eval() const {
   1880     return IsPossiblyEvalField::decode(bit_field_);
   1881   }
   1882 
   1883   TailCallMode tail_call_mode() const {
   1884     return IsTailField::decode(bit_field_) ? TailCallMode::kAllow
   1885                                            : TailCallMode::kDisallow;
   1886   }
   1887   void MarkTail() { bit_field_ = IsTailField::update(bit_field_, true); }
   1888 
   1889   bool only_last_arg_is_spread() {
   1890     return !arguments_->is_empty() && arguments_->last()->IsSpread();
   1891   }
   1892 
   1893   enum CallType {
   1894     GLOBAL_CALL,
   1895     WITH_CALL,
   1896     NAMED_PROPERTY_CALL,
   1897     KEYED_PROPERTY_CALL,
   1898     NAMED_SUPER_PROPERTY_CALL,
   1899     KEYED_SUPER_PROPERTY_CALL,
   1900     SUPER_CALL,
   1901     OTHER_CALL
   1902   };
   1903 
   1904   enum PossiblyEval {
   1905     IS_POSSIBLY_EVAL,
   1906     NOT_EVAL,
   1907   };
   1908 
   1909   // Helpers to determine how to handle the call.
   1910   CallType GetCallType() const;
   1911 
   1912 #ifdef DEBUG
   1913   // Used to assert that the FullCodeGenerator records the return site.
   1914   bool return_is_recorded_;
   1915 #endif
   1916 
   1917  private:
   1918   friend class AstNodeFactory;
   1919 
   1920   Call(Expression* expression, ZoneList<Expression*>* arguments, int pos,
   1921        PossiblyEval possibly_eval)
   1922       : Expression(pos, kCall),
   1923         expression_(expression),
   1924         arguments_(arguments) {
   1925     bit_field_ |=
   1926         IsUninitializedField::encode(false) |
   1927         IsPossiblyEvalField::encode(possibly_eval == IS_POSSIBLY_EVAL);
   1928 
   1929     if (expression->IsProperty()) {
   1930       expression->AsProperty()->mark_for_call();
   1931     }
   1932   }
   1933 
   1934   static int parent_num_ids() { return Expression::num_ids(); }
   1935   int local_id(int n) const { return base_id() + parent_num_ids() + n; }
   1936 
   1937   class IsUninitializedField
   1938       : public BitField<bool, Expression::kNextBitFieldIndex, 1> {};
   1939   class IsTailField : public BitField<bool, IsUninitializedField::kNext, 1> {};
   1940   class IsPossiblyEvalField : public BitField<bool, IsTailField::kNext, 1> {};
   1941 
   1942   FeedbackSlot ic_slot_;
   1943   Expression* expression_;
   1944   ZoneList<Expression*>* arguments_;
   1945   Handle<JSFunction> target_;
   1946   Handle<AllocationSite> allocation_site_;
   1947 };
   1948 
   1949 
   1950 class CallNew final : public Expression {
   1951  public:
   1952   Expression* expression() const { return expression_; }
   1953   ZoneList<Expression*>* arguments() const { return arguments_; }
   1954 
   1955   void set_expression(Expression* e) { expression_ = e; }
   1956 
   1957   // Type feedback information.
   1958   void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
   1959                            FeedbackSlotCache* cache) {
   1960     // CallNew stores feedback in the exact same way as Call. We can
   1961     // piggyback on the type feedback infrastructure for calls.
   1962     callnew_feedback_slot_ = spec->AddCallICSlot();
   1963   }
   1964 
   1965   FeedbackSlot CallNewFeedbackSlot() {
   1966     DCHECK(!callnew_feedback_slot_.IsInvalid());
   1967     return callnew_feedback_slot_;
   1968   }
   1969 
   1970   bool IsMonomorphic() const { return IsMonomorphicField::decode(bit_field_); }
   1971   Handle<JSFunction> target() const { return target_; }
   1972   Handle<AllocationSite> allocation_site() const {
   1973     return allocation_site_;
   1974   }
   1975 
   1976   static int num_ids() { return parent_num_ids() + 1; }
   1977   static int feedback_slots() { return 1; }
   1978   BailoutId ReturnId() const { return BailoutId(local_id(0)); }
   1979 
   1980   void set_allocation_site(Handle<AllocationSite> site) {
   1981     allocation_site_ = site;
   1982   }
   1983   void set_is_monomorphic(bool monomorphic) {
   1984     bit_field_ = IsMonomorphicField::update(bit_field_, monomorphic);
   1985   }
   1986   void set_target(Handle<JSFunction> target) { target_ = target; }
   1987   void SetKnownGlobalTarget(Handle<JSFunction> target) {
   1988     target_ = target;
   1989     set_is_monomorphic(true);
   1990   }
   1991 
   1992   bool only_last_arg_is_spread() {
   1993     return !arguments_->is_empty() && arguments_->last()->IsSpread();
   1994   }
   1995 
   1996  private:
   1997   friend class AstNodeFactory;
   1998 
   1999   CallNew(Expression* expression, ZoneList<Expression*>* arguments, int pos)
   2000       : Expression(pos, kCallNew),
   2001         expression_(expression),
   2002         arguments_(arguments) {
   2003     bit_field_ |= IsMonomorphicField::encode(false);
   2004   }
   2005 
   2006   static int parent_num_ids() { return Expression::num_ids(); }
   2007   int local_id(int n) const { return base_id() + parent_num_ids() + n; }
   2008 
   2009   FeedbackSlot callnew_feedback_slot_;
   2010   Expression* expression_;
   2011   ZoneList<Expression*>* arguments_;
   2012   Handle<JSFunction> target_;
   2013   Handle<AllocationSite> allocation_site_;
   2014 
   2015   class IsMonomorphicField
   2016       : public BitField<bool, Expression::kNextBitFieldIndex, 1> {};
   2017 };
   2018 
   2019 
   2020 // The CallRuntime class does not represent any official JavaScript
   2021 // language construct. Instead it is used to call a C or JS function
   2022 // with a set of arguments. This is used from the builtins that are
   2023 // implemented in JavaScript (see "v8natives.js").
   2024 class CallRuntime final : public Expression {
   2025  public:
   2026   ZoneList<Expression*>* arguments() const { return arguments_; }
   2027   bool is_jsruntime() const { return function_ == NULL; }
   2028 
   2029   int context_index() const {
   2030     DCHECK(is_jsruntime());
   2031     return context_index_;
   2032   }
   2033   void set_context_index(int index) {
   2034     DCHECK(is_jsruntime());
   2035     context_index_ = index;
   2036   }
   2037   const Runtime::Function* function() const {
   2038     DCHECK(!is_jsruntime());
   2039     return function_;
   2040   }
   2041 
   2042   static int num_ids() { return parent_num_ids() + 1; }
   2043   BailoutId CallId() { return BailoutId(local_id(0)); }
   2044   const char* debug_name();
   2045 
   2046  private:
   2047   friend class AstNodeFactory;
   2048 
   2049   CallRuntime(const Runtime::Function* function,
   2050               ZoneList<Expression*>* arguments, int pos)
   2051       : Expression(pos, kCallRuntime),
   2052         function_(function),
   2053         arguments_(arguments) {}
   2054   CallRuntime(int context_index, ZoneList<Expression*>* arguments, int pos)
   2055       : Expression(pos, kCallRuntime),
   2056         context_index_(context_index),
   2057         function_(NULL),
   2058         arguments_(arguments) {}
   2059 
   2060   static int parent_num_ids() { return Expression::num_ids(); }
   2061   int local_id(int n) const { return base_id() + parent_num_ids() + n; }
   2062 
   2063   int context_index_;
   2064   const Runtime::Function* function_;
   2065   ZoneList<Expression*>* arguments_;
   2066 };
   2067 
   2068 
   2069 class UnaryOperation final : public Expression {
   2070  public:
   2071   Token::Value op() const { return OperatorField::decode(bit_field_); }
   2072   Expression* expression() const { return expression_; }
   2073   void set_expression(Expression* e) { expression_ = e; }
   2074 
   2075   // For unary not (Token::NOT), the AST ids where true and false will
   2076   // actually be materialized, respectively.
   2077   static int num_ids() { return parent_num_ids() + 2; }
   2078   BailoutId MaterializeTrueId() const { return BailoutId(local_id(0)); }
   2079   BailoutId MaterializeFalseId() const { return BailoutId(local_id(1)); }
   2080 
   2081   void RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle);
   2082 
   2083  private:
   2084   friend class AstNodeFactory;
   2085 
   2086   UnaryOperation(Token::Value op, Expression* expression, int pos)
   2087       : Expression(pos, kUnaryOperation), expression_(expression) {
   2088     bit_field_ |= OperatorField::encode(op);
   2089     DCHECK(Token::IsUnaryOp(op));
   2090   }
   2091 
   2092   static int parent_num_ids() { return Expression::num_ids(); }
   2093   int local_id(int n) const { return base_id() + parent_num_ids() + n; }
   2094 
   2095   Expression* expression_;
   2096 
   2097   class OperatorField
   2098       : public BitField<Token::Value, Expression::kNextBitFieldIndex, 7> {};
   2099 };
   2100 
   2101 
   2102 class BinaryOperation final : public Expression {
   2103  public:
   2104   Token::Value op() const { return OperatorField::decode(bit_field_); }
   2105   Expression* left() const { return left_; }
   2106   void set_left(Expression* e) { left_ = e; }
   2107   Expression* right() const { return right_; }
   2108   void set_right(Expression* e) { right_ = e; }
   2109   Handle<AllocationSite> allocation_site() const { return allocation_site_; }
   2110   void set_allocation_site(Handle<AllocationSite> allocation_site) {
   2111     allocation_site_ = allocation_site;
   2112   }
   2113 
   2114   void MarkTail() {
   2115     switch (op()) {
   2116       case Token::COMMA:
   2117       case Token::AND:
   2118       case Token::OR:
   2119         right_->MarkTail();
   2120       default:
   2121         break;
   2122     }
   2123   }
   2124 
   2125   // The short-circuit logical operations need an AST ID for their
   2126   // right-hand subexpression.
   2127   static int num_ids() { return parent_num_ids() + 2; }
   2128   BailoutId RightId() const { return BailoutId(local_id(0)); }
   2129 
   2130   // BinaryOperation will have both a slot in the feedback vector and the
   2131   // TypeFeedbackId to record the type information. TypeFeedbackId is used
   2132   // by full codegen and the feedback vector slot is used by interpreter.
   2133   void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
   2134                            FeedbackSlotCache* cache);
   2135 
   2136   FeedbackSlot BinaryOperationFeedbackSlot() const { return feedback_slot_; }
   2137 
   2138   TypeFeedbackId BinaryOperationFeedbackId() const {
   2139     return TypeFeedbackId(local_id(1));
   2140   }
   2141   Maybe<int> fixed_right_arg() const {
   2142     return has_fixed_right_arg_ ? Just(fixed_right_arg_value_) : Nothing<int>();
   2143   }
   2144   void set_fixed_right_arg(Maybe<int> arg) {
   2145     has_fixed_right_arg_ = arg.IsJust();
   2146     if (arg.IsJust()) fixed_right_arg_value_ = arg.FromJust();
   2147   }
   2148 
   2149   void RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle);
   2150 
   2151  private:
   2152   friend class AstNodeFactory;
   2153 
   2154   BinaryOperation(Token::Value op, Expression* left, Expression* right, int pos)
   2155       : Expression(pos, kBinaryOperation),
   2156         has_fixed_right_arg_(false),
   2157         fixed_right_arg_value_(0),
   2158         left_(left),
   2159         right_(right) {
   2160     bit_field_ |= OperatorField::encode(op);
   2161     DCHECK(Token::IsBinaryOp(op));
   2162   }
   2163 
   2164   static int parent_num_ids() { return Expression::num_ids(); }
   2165   int local_id(int n) const { return base_id() + parent_num_ids() + n; }
   2166 
   2167   // TODO(rossberg): the fixed arg should probably be represented as a Constant
   2168   // type for the RHS. Currenty it's actually a Maybe<int>
   2169   bool has_fixed_right_arg_;
   2170   int fixed_right_arg_value_;
   2171   Expression* left_;
   2172   Expression* right_;
   2173   Handle<AllocationSite> allocation_site_;
   2174   FeedbackSlot feedback_slot_;
   2175 
   2176   class OperatorField
   2177       : public BitField<Token::Value, Expression::kNextBitFieldIndex, 7> {};
   2178 };
   2179 
   2180 
   2181 class CountOperation final : public Expression {
   2182  public:
   2183   bool is_prefix() const { return IsPrefixField::decode(bit_field_); }
   2184   bool is_postfix() const { return !is_prefix(); }
   2185 
   2186   Token::Value op() const { return TokenField::decode(bit_field_); }
   2187   Token::Value binary_op() {
   2188     return (op() == Token::INC) ? Token::ADD : Token::SUB;
   2189   }
   2190 
   2191   Expression* expression() const { return expression_; }
   2192   void set_expression(Expression* e) { expression_ = e; }
   2193 
   2194   bool IsMonomorphic() const { return receiver_types_.length() == 1; }
   2195   SmallMapList* GetReceiverTypes() { return &receiver_types_; }
   2196   IcCheckType GetKeyType() const { return KeyTypeField::decode(bit_field_); }
   2197   KeyedAccessStoreMode GetStoreMode() const {
   2198     return StoreModeField::decode(bit_field_);
   2199   }
   2200   AstType* type() const { return type_; }
   2201   void set_key_type(IcCheckType type) {
   2202     bit_field_ = KeyTypeField::update(bit_field_, type);
   2203   }
   2204   void set_store_mode(KeyedAccessStoreMode mode) {
   2205     bit_field_ = StoreModeField::update(bit_field_, mode);
   2206   }
   2207   void set_type(AstType* type) { type_ = type; }
   2208 
   2209   static int num_ids() { return parent_num_ids() + 4; }
   2210   BailoutId AssignmentId() const { return BailoutId(local_id(0)); }
   2211   BailoutId ToNumberId() const { return BailoutId(local_id(1)); }
   2212   TypeFeedbackId CountBinOpFeedbackId() const {
   2213     return TypeFeedbackId(local_id(2));
   2214   }
   2215   TypeFeedbackId CountStoreFeedbackId() const {
   2216     return TypeFeedbackId(local_id(3));
   2217   }
   2218 
   2219   // Feedback slot for binary operation is only used by ignition.
   2220   FeedbackSlot CountBinaryOpFeedbackSlot() const {
   2221     return binary_operation_slot_;
   2222   }
   2223 
   2224   void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
   2225                            FeedbackSlotCache* cache);
   2226   FeedbackSlot CountSlot() const { return slot_; }
   2227 
   2228  private:
   2229   friend class AstNodeFactory;
   2230 
   2231   CountOperation(Token::Value op, bool is_prefix, Expression* expr, int pos)
   2232       : Expression(pos, kCountOperation), type_(NULL), expression_(expr) {
   2233     bit_field_ |=
   2234         IsPrefixField::encode(is_prefix) | KeyTypeField::encode(ELEMENT) |
   2235         StoreModeField::encode(STANDARD_STORE) | TokenField::encode(op);
   2236   }
   2237 
   2238   static int parent_num_ids() { return Expression::num_ids(); }
   2239   int local_id(int n) const { return base_id() + parent_num_ids() + n; }
   2240 
   2241   class IsPrefixField
   2242       : public BitField<bool, Expression::kNextBitFieldIndex, 1> {};
   2243   class KeyTypeField : public BitField<IcCheckType, IsPrefixField::kNext, 1> {};
   2244   class StoreModeField
   2245       : public BitField<KeyedAccessStoreMode, KeyTypeField::kNext, 3> {};
   2246   class TokenField : public BitField<Token::Value, StoreModeField::kNext, 7> {};
   2247 
   2248   FeedbackSlot slot_;
   2249   FeedbackSlot binary_operation_slot_;
   2250   AstType* type_;
   2251   Expression* expression_;
   2252   SmallMapList receiver_types_;
   2253 };
   2254 
   2255 
   2256 class CompareOperation final : public Expression {
   2257  public:
   2258   Token::Value op() const { return OperatorField::decode(bit_field_); }
   2259   Expression* left() const { return left_; }
   2260   Expression* right() const { return right_; }
   2261 
   2262   void set_left(Expression* e) { left_ = e; }
   2263   void set_right(Expression* e) { right_ = e; }
   2264 
   2265   // Type feedback information.
   2266   static int num_ids() { return parent_num_ids() + 1; }
   2267   TypeFeedbackId CompareOperationFeedbackId() const {
   2268     return TypeFeedbackId(local_id(0));
   2269   }
   2270   AstType* combined_type() const { return combined_type_; }
   2271   void set_combined_type(AstType* type) { combined_type_ = type; }
   2272 
   2273   // CompareOperation will have both a slot in the feedback vector and the
   2274   // TypeFeedbackId to record the type information. TypeFeedbackId is used
   2275   // by full codegen and the feedback vector slot is used by interpreter.
   2276   void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
   2277                            FeedbackSlotCache* cache);
   2278 
   2279   FeedbackSlot CompareOperationFeedbackSlot() const { return feedback_slot_; }
   2280 
   2281   // Match special cases.
   2282   bool IsLiteralCompareTypeof(Expression** expr, Handle<String>* check);
   2283   bool IsLiteralCompareUndefined(Expression** expr);
   2284   bool IsLiteralCompareNull(Expression** expr);
   2285 
   2286  private:
   2287   friend class AstNodeFactory;
   2288 
   2289   CompareOperation(Token::Value op, Expression* left, Expression* right,
   2290                    int pos)
   2291       : Expression(pos, kCompareOperation),
   2292         left_(left),
   2293         right_(right),
   2294         combined_type_(AstType::None()) {
   2295     bit_field_ |= OperatorField::encode(op);
   2296     DCHECK(Token::IsCompareOp(op));
   2297   }
   2298 
   2299   static int parent_num_ids() { return Expression::num_ids(); }
   2300   int local_id(int n) const { return base_id() + parent_num_ids() + n; }
   2301 
   2302   Expression* left_;
   2303   Expression* right_;
   2304 
   2305   AstType* combined_type_;
   2306   FeedbackSlot feedback_slot_;
   2307   class OperatorField
   2308       : public BitField<Token::Value, Expression::kNextBitFieldIndex, 7> {};
   2309 };
   2310 
   2311 
   2312 class Spread final : public Expression {
   2313  public:
   2314   Expression* expression() const { return expression_; }
   2315   void set_expression(Expression* e) { expression_ = e; }
   2316 
   2317   int expression_position() const { return expr_pos_; }
   2318 
   2319   static int num_ids() { return parent_num_ids(); }
   2320 
   2321  private:
   2322   friend class AstNodeFactory;
   2323 
   2324   Spread(Expression* expression, int pos, int expr_pos)
   2325       : Expression(pos, kSpread),
   2326         expr_pos_(expr_pos),
   2327         expression_(expression) {}
   2328 
   2329   static int parent_num_ids() { return Expression::num_ids(); }
   2330   int local_id(int n) const { return base_id() + parent_num_ids() + n; }
   2331 
   2332   int expr_pos_;
   2333   Expression* expression_;
   2334 };
   2335 
   2336 
   2337 class Conditional final : public Expression {
   2338  public:
   2339   Expression* condition() const { return condition_; }
   2340   Expression* then_expression() const { return then_expression_; }
   2341   Expression* else_expression() const { return else_expression_; }
   2342 
   2343   void set_condition(Expression* e) { condition_ = e; }
   2344   void set_then_expression(Expression* e) { then_expression_ = e; }
   2345   void set_else_expression(Expression* e) { else_expression_ = e; }
   2346 
   2347   void MarkTail() {
   2348     then_expression_->MarkTail();
   2349     else_expression_->MarkTail();
   2350   }
   2351 
   2352   static int num_ids() { return parent_num_ids() + 2; }
   2353   BailoutId ThenId() const { return BailoutId(local_id(0)); }
   2354   BailoutId ElseId() const { return BailoutId(local_id(1)); }
   2355 
   2356  private:
   2357   friend class AstNodeFactory;
   2358 
   2359   Conditional(Expression* condition, Expression* then_expression,
   2360               Expression* else_expression, int position)
   2361       : Expression(position, kConditional),
   2362         condition_(condition),
   2363         then_expression_(then_expression),
   2364         else_expression_(else_expression) {}
   2365 
   2366   static int parent_num_ids() { return Expression::num_ids(); }
   2367   int local_id(int n) const { return base_id() + parent_num_ids() + n; }
   2368 
   2369   Expression* condition_;
   2370   Expression* then_expression_;
   2371   Expression* else_expression_;
   2372 };
   2373 
   2374 
   2375 class Assignment final : public Expression {
   2376  public:
   2377   Assignment* AsSimpleAssignment() { return !is_compound() ? this : NULL; }
   2378 
   2379   Token::Value binary_op() const;
   2380 
   2381   Token::Value op() const { return TokenField::decode(bit_field_); }
   2382   Expression* target() const { return target_; }
   2383   Expression* value() const { return value_; }
   2384 
   2385   void set_target(Expression* e) { target_ = e; }
   2386   void set_value(Expression* e) { value_ = e; }
   2387 
   2388   BinaryOperation* binary_operation() const { return binary_operation_; }
   2389 
   2390   // This check relies on the definition order of token in token.h.
   2391   bool is_compound() const { return op() > Token::ASSIGN; }
   2392 
   2393   static int num_ids() { return parent_num_ids() + 2; }
   2394   BailoutId AssignmentId() const { return BailoutId(local_id(0)); }
   2395 
   2396   // Type feedback information.
   2397   TypeFeedbackId AssignmentFeedbackId() { return TypeFeedbackId(local_id(1)); }
   2398   bool IsUninitialized() const {
   2399     return IsUninitializedField::decode(bit_field_);
   2400   }
   2401   bool HasNoTypeInformation() {
   2402     return IsUninitializedField::decode(bit_field_);
   2403   }
   2404   bool IsMonomorphic() const { return receiver_types_.length() == 1; }
   2405   SmallMapList* GetReceiverTypes() { return &receiver_types_; }
   2406   IcCheckType GetKeyType() const { return KeyTypeField::decode(bit_field_); }
   2407   KeyedAccessStoreMode GetStoreMode() const {
   2408     return StoreModeField::decode(bit_field_);
   2409   }
   2410   void set_is_uninitialized(bool b) {
   2411     bit_field_ = IsUninitializedField::update(bit_field_, b);
   2412   }
   2413   void set_key_type(IcCheckType key_type) {
   2414     bit_field_ = KeyTypeField::update(bit_field_, key_type);
   2415   }
   2416   void set_store_mode(KeyedAccessStoreMode mode) {
   2417     bit_field_ = StoreModeField::update(bit_field_, mode);
   2418   }
   2419 
   2420   void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
   2421                            FeedbackSlotCache* cache);
   2422   FeedbackSlot AssignmentSlot() const { return slot_; }
   2423 
   2424  private:
   2425   friend class AstNodeFactory;
   2426 
   2427   Assignment(Token::Value op, Expression* target, Expression* value, int pos);
   2428 
   2429   static int parent_num_ids() { return Expression::num_ids(); }
   2430   int local_id(int n) const { return base_id() + parent_num_ids() + n; }
   2431 
   2432   class IsUninitializedField
   2433       : public BitField<bool, Expression::kNextBitFieldIndex, 1> {};
   2434   class KeyTypeField
   2435       : public BitField<IcCheckType, IsUninitializedField::kNext, 1> {};
   2436   class StoreModeField
   2437       : public BitField<KeyedAccessStoreMode, KeyTypeField::kNext, 3> {};
   2438   class TokenField : public BitField<Token::Value, StoreModeField::kNext, 7> {};
   2439 
   2440   FeedbackSlot slot_;
   2441   Expression* target_;
   2442   Expression* value_;
   2443   BinaryOperation* binary_operation_;
   2444   SmallMapList receiver_types_;
   2445 };
   2446 
   2447 
   2448 // The RewritableExpression class is a wrapper for AST nodes that wait
   2449 // for some potential rewriting.  However, even if such nodes are indeed
   2450 // rewritten, the RewritableExpression wrapper nodes will survive in the
   2451 // final AST and should be just ignored, i.e., they should be treated as
   2452 // equivalent to the wrapped nodes.  For this reason and to simplify later
   2453 // phases, RewritableExpressions are considered as exceptions of AST nodes
   2454 // in the following sense:
   2455 //
   2456 // 1. IsRewritableExpression and AsRewritableExpression behave as usual.
   2457 // 2. All other Is* and As* methods are practically delegated to the
   2458 //    wrapped node, i.e. IsArrayLiteral() will return true iff the
   2459 //    wrapped node is an array literal.
   2460 //
   2461 // Furthermore, an invariant that should be respected is that the wrapped
   2462 // node is not a RewritableExpression.
   2463 class RewritableExpression final : public Expression {
   2464  public:
   2465   Expression* expression() const { return expr_; }
   2466   bool is_rewritten() const { return IsRewrittenField::decode(bit_field_); }
   2467 
   2468   void Rewrite(Expression* new_expression) {
   2469     DCHECK(!is_rewritten());
   2470     DCHECK_NOT_NULL(new_expression);
   2471     DCHECK(!new_expression->IsRewritableExpression());
   2472     expr_ = new_expression;
   2473     bit_field_ = IsRewrittenField::update(bit_field_, true);
   2474   }
   2475 
   2476   static int num_ids() { return parent_num_ids(); }
   2477 
   2478  private:
   2479   friend class AstNodeFactory;
   2480 
   2481   explicit RewritableExpression(Expression* expression)
   2482       : Expression(expression->position(), kRewritableExpression),
   2483         expr_(expression) {
   2484     bit_field_ |= IsRewrittenField::encode(false);
   2485     DCHECK(!expression->IsRewritableExpression());
   2486   }
   2487 
   2488   int local_id(int n) const { return base_id() + parent_num_ids() + n; }
   2489 
   2490   Expression* expr_;
   2491 
   2492   class IsRewrittenField
   2493       : public BitField<bool, Expression::kNextBitFieldIndex, 1> {};
   2494 };
   2495 
   2496 // Our Yield is different from the JS yield in that it "returns" its argument as
   2497 // is, without wrapping it in an iterator result object.  Such wrapping, if
   2498 // desired, must be done beforehand (see the parser).
   2499 class Yield final : public Expression {
   2500  public:
   2501   enum OnException { kOnExceptionThrow, kOnExceptionRethrow };
   2502 
   2503   Expression* generator_object() const { return generator_object_; }
   2504   Expression* expression() const { return expression_; }
   2505   OnException on_exception() const {
   2506     return OnExceptionField::decode(bit_field_);
   2507   }
   2508   bool rethrow_on_exception() const {
   2509     return on_exception() == kOnExceptionRethrow;
   2510   }
   2511   int yield_id() const { return yield_id_; }
   2512 
   2513   void set_generator_object(Expression* e) { generator_object_ = e; }
   2514   void set_expression(Expression* e) { expression_ = e; }
   2515   void set_yield_id(int yield_id) { yield_id_ = yield_id; }
   2516 
   2517  private:
   2518   friend class AstNodeFactory;
   2519 
   2520   Yield(Expression* generator_object, Expression* expression, int pos,
   2521         OnException on_exception)
   2522       : Expression(pos, kYield),
   2523         yield_id_(-1),
   2524         generator_object_(generator_object),
   2525         expression_(expression) {
   2526     bit_field_ |= OnExceptionField::encode(on_exception);
   2527   }
   2528 
   2529   int yield_id_;
   2530   Expression* generator_object_;
   2531   Expression* expression_;
   2532 
   2533   class OnExceptionField
   2534       : public BitField<OnException, Expression::kNextBitFieldIndex, 1> {};
   2535 };
   2536 
   2537 
   2538 class Throw final : public Expression {
   2539  public:
   2540   Expression* exception() const { return exception_; }
   2541   void set_exception(Expression* e) { exception_ = e; }
   2542 
   2543  private:
   2544   friend class AstNodeFactory;
   2545 
   2546   Throw(Expression* exception, int pos)
   2547       : Expression(pos, kThrow), exception_(exception) {}
   2548 
   2549   Expression* exception_;
   2550 };
   2551 
   2552 
   2553 class FunctionLiteral final : public Expression {
   2554  public:
   2555   enum FunctionType {
   2556     kAnonymousExpression,
   2557     kNamedExpression,
   2558     kDeclaration,
   2559     kAccessorOrMethod
   2560   };
   2561 
   2562   enum IdType { kIdTypeInvalid = -1, kIdTypeTopLevel = 0 };
   2563 
   2564   enum ParameterFlag { kNoDuplicateParameters, kHasDuplicateParameters };
   2565 
   2566   enum EagerCompileHint { kShouldEagerCompile, kShouldLazyCompile };
   2567 
   2568   Handle<String> name() const { return raw_name_->string(); }
   2569   const AstString* raw_name() const { return raw_name_; }
   2570   void set_raw_name(const AstString* name) { raw_name_ = name; }
   2571   DeclarationScope* scope() const { return scope_; }
   2572   ZoneList<Statement*>* body() const { return body_; }
   2573   void set_function_token_position(int pos) { function_token_position_ = pos; }
   2574   int function_token_position() const { return function_token_position_; }
   2575   int start_position() const;
   2576   int end_position() const;
   2577   int SourceSize() const { return end_position() - start_position(); }
   2578   bool is_declaration() const { return function_type() == kDeclaration; }
   2579   bool is_named_expression() const {
   2580     return function_type() == kNamedExpression;
   2581   }
   2582   bool is_anonymous_expression() const {
   2583     return function_type() == kAnonymousExpression;
   2584   }
   2585   LanguageMode language_mode() const;
   2586 
   2587   void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
   2588                            FeedbackSlotCache* cache) {
   2589     literal_feedback_slot_ = spec->AddCreateClosureSlot();
   2590   }
   2591 
   2592   FeedbackSlot LiteralFeedbackSlot() const { return literal_feedback_slot_; }
   2593 
   2594   static bool NeedsHomeObject(Expression* expr);
   2595 
   2596   int expected_property_count() { return expected_property_count_; }
   2597   int parameter_count() { return parameter_count_; }
   2598   int function_length() { return function_length_; }
   2599 
   2600   bool AllowsLazyCompilation();
   2601 
   2602   Handle<String> debug_name() const {
   2603     if (raw_name_ != NULL && !raw_name_->IsEmpty()) {
   2604       return raw_name_->string();
   2605     }
   2606     return inferred_name();
   2607   }
   2608 
   2609   Handle<String> inferred_name() const {
   2610     if (!inferred_name_.is_null()) {
   2611       DCHECK(raw_inferred_name_ == NULL);
   2612       return inferred_name_;
   2613     }
   2614     if (raw_inferred_name_ != NULL) {
   2615       return raw_inferred_name_->string();
   2616     }
   2617     UNREACHABLE();
   2618     return Handle<String>();
   2619   }
   2620 
   2621   // Only one of {set_inferred_name, set_raw_inferred_name} should be called.
   2622   void set_inferred_name(Handle<String> inferred_name) {
   2623     DCHECK(!inferred_name.is_null());
   2624     inferred_name_ = inferred_name;
   2625     DCHECK(raw_inferred_name_== NULL || raw_inferred_name_->IsEmpty());
   2626     raw_inferred_name_ = NULL;
   2627   }
   2628 
   2629   void set_raw_inferred_name(const AstString* raw_inferred_name) {
   2630     DCHECK(raw_inferred_name != NULL);
   2631     raw_inferred_name_ = raw_inferred_name;
   2632     DCHECK(inferred_name_.is_null());
   2633     inferred_name_ = Handle<String>();
   2634   }
   2635 
   2636   bool pretenure() const { return Pretenure::decode(bit_field_); }
   2637   void set_pretenure() { bit_field_ = Pretenure::update(bit_field_, true); }
   2638 
   2639   bool has_duplicate_parameters() const {
   2640     return HasDuplicateParameters::decode(bit_field_);
   2641   }
   2642 
   2643   // This is used as a heuristic on when to eagerly compile a function
   2644   // literal. We consider the following constructs as hints that the
   2645   // function will be called immediately:
   2646   // - (function() { ... })();
   2647   // - var x = function() { ... }();
   2648   bool ShouldEagerCompile() const;
   2649   void SetShouldEagerCompile();
   2650 
   2651   // A hint that we expect this function to be called (exactly) once,
   2652   // i.e. we suspect it's an initialization function.
   2653   bool should_be_used_once_hint() const {
   2654     return ShouldNotBeUsedOnceHintField::decode(bit_field_);
   2655   }
   2656   void set_should_be_used_once_hint() {
   2657     bit_field_ = ShouldNotBeUsedOnceHintField::update(bit_field_, true);
   2658   }
   2659 
   2660   FunctionType function_type() const {
   2661     return FunctionTypeBits::decode(bit_field_);
   2662   }
   2663   FunctionKind kind() const;
   2664 
   2665   int ast_node_count() { return ast_properties_.node_count(); }
   2666   AstProperties::Flags flags() const { return ast_properties_.flags(); }
   2667   void set_ast_properties(AstProperties* ast_properties) {
   2668     ast_properties_ = *ast_properties;
   2669   }
   2670   const FeedbackVectorSpec* feedback_vector_spec() const {
   2671     return ast_properties_.get_spec();
   2672   }
   2673   bool dont_optimize() { return dont_optimize_reason() != kNoReason; }
   2674   BailoutReason dont_optimize_reason() {
   2675     return DontOptimizeReasonField::decode(bit_field_);
   2676   }
   2677   void set_dont_optimize_reason(BailoutReason reason) {
   2678     bit_field_ = DontOptimizeReasonField::update(bit_field_, reason);
   2679   }
   2680 
   2681   bool IsAnonymousFunctionDefinition() const {
   2682     return is_anonymous_expression();
   2683   }
   2684 
   2685   int yield_count() { return yield_count_; }
   2686   void set_yield_count(int yield_count) { yield_count_ = yield_count; }
   2687 
   2688   int return_position() {
   2689     return std::max(start_position(), end_position() - (has_braces_ ? 1 : 0));
   2690   }
   2691 
   2692   int function_literal_id() const { return function_literal_id_; }
   2693   void set_function_literal_id(int function_literal_id) {
   2694     function_literal_id_ = function_literal_id;
   2695   }
   2696 
   2697  private:
   2698   friend class AstNodeFactory;
   2699 
   2700   FunctionLiteral(Zone* zone, const AstString* name,
   2701                   AstValueFactory* ast_value_factory, DeclarationScope* scope,
   2702                   ZoneList<Statement*>* body, int expected_property_count,
   2703                   int parameter_count, int function_length,
   2704                   FunctionType function_type,
   2705                   ParameterFlag has_duplicate_parameters,
   2706                   EagerCompileHint eager_compile_hint, int position,
   2707                   bool has_braces, int function_literal_id)
   2708       : Expression(position, kFunctionLiteral),
   2709         expected_property_count_(expected_property_count),
   2710         parameter_count_(parameter_count),
   2711         function_length_(function_length),
   2712         function_token_position_(kNoSourcePosition),
   2713         yield_count_(0),
   2714         has_braces_(has_braces),
   2715         raw_name_(name),
   2716         scope_(scope),
   2717         body_(body),
   2718         raw_inferred_name_(ast_value_factory->empty_string()),
   2719         ast_properties_(zone),
   2720         function_literal_id_(function_literal_id) {
   2721     bit_field_ |= FunctionTypeBits::encode(function_type) |
   2722                   Pretenure::encode(false) |
   2723                   HasDuplicateParameters::encode(has_duplicate_parameters ==
   2724                                                  kHasDuplicateParameters) |
   2725                   ShouldNotBeUsedOnceHintField::encode(false) |
   2726                   DontOptimizeReasonField::encode(kNoReason);
   2727     if (eager_compile_hint == kShouldEagerCompile) SetShouldEagerCompile();
   2728   }
   2729 
   2730   class FunctionTypeBits
   2731       : public BitField<FunctionType, Expression::kNextBitFieldIndex, 2> {};
   2732   class Pretenure : public BitField<bool, FunctionTypeBits::kNext, 1> {};
   2733   class HasDuplicateParameters : public BitField<bool, Pretenure::kNext, 1> {};
   2734   class ShouldNotBeUsedOnceHintField
   2735       : public BitField<bool, HasDuplicateParameters::kNext, 1> {};
   2736   class DontOptimizeReasonField
   2737       : public BitField<BailoutReason, ShouldNotBeUsedOnceHintField::kNext, 8> {
   2738   };
   2739 
   2740   int expected_property_count_;
   2741   int parameter_count_;
   2742   int function_length_;
   2743   int function_token_position_;
   2744   int yield_count_;
   2745   bool has_braces_;
   2746 
   2747   const AstString* raw_name_;
   2748   DeclarationScope* scope_;
   2749   ZoneList<Statement*>* body_;
   2750   const AstString* raw_inferred_name_;
   2751   Handle<String> inferred_name_;
   2752   AstProperties ast_properties_;
   2753   int function_literal_id_;
   2754   FeedbackSlot literal_feedback_slot_;
   2755 };
   2756 
   2757 // Property is used for passing information
   2758 // about a class literal's properties from the parser to the code generator.
   2759 class ClassLiteralProperty final : public LiteralProperty {
   2760  public:
   2761   enum Kind : uint8_t { METHOD, GETTER, SETTER, FIELD };
   2762 
   2763   Kind kind() const { return kind_; }
   2764 
   2765   bool is_static() const { return is_static_; }
   2766 
   2767  private:
   2768   friend class AstNodeFactory;
   2769 
   2770   ClassLiteralProperty(Expression* key, Expression* value, Kind kind,
   2771                        bool is_static, bool is_computed_name);
   2772 
   2773   Kind kind_;
   2774   bool is_static_;
   2775 };
   2776 
   2777 class ClassLiteral final : public Expression {
   2778  public:
   2779   typedef ClassLiteralProperty Property;
   2780 
   2781   VariableProxy* class_variable_proxy() const { return class_variable_proxy_; }
   2782   Expression* extends() const { return extends_; }
   2783   void set_extends(Expression* e) { extends_ = e; }
   2784   FunctionLiteral* constructor() const { return constructor_; }
   2785   void set_constructor(FunctionLiteral* f) { constructor_ = f; }
   2786   ZoneList<Property*>* properties() const { return properties_; }
   2787   int start_position() const { return position(); }
   2788   int end_position() const { return end_position_; }
   2789   bool has_name_static_property() const {
   2790     return HasNameStaticProperty::decode(bit_field_);
   2791   }
   2792   bool has_static_computed_names() const {
   2793     return HasStaticComputedNames::decode(bit_field_);
   2794   }
   2795 
   2796   // Object literals need one feedback slot for each non-trivial value, as well
   2797   // as some slots for home objects.
   2798   void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
   2799                            FeedbackSlotCache* cache);
   2800 
   2801   bool NeedsProxySlot() const {
   2802     return class_variable_proxy() != nullptr &&
   2803            class_variable_proxy()->var()->IsUnallocated();
   2804   }
   2805 
   2806   FeedbackSlot HomeObjectSlot() const { return home_object_slot_; }
   2807   FeedbackSlot ProxySlot() const { return proxy_slot_; }
   2808 
   2809  private:
   2810   friend class AstNodeFactory;
   2811 
   2812   ClassLiteral(VariableProxy* class_variable_proxy, Expression* extends,
   2813                FunctionLiteral* constructor, ZoneList<Property*>* properties,
   2814                int start_position, int end_position,
   2815                bool has_name_static_property, bool has_static_computed_names)
   2816       : Expression(start_position, kClassLiteral),
   2817         end_position_(end_position),
   2818         class_variable_proxy_(class_variable_proxy),
   2819         extends_(extends),
   2820         constructor_(constructor),
   2821         properties_(properties) {
   2822     bit_field_ |= HasNameStaticProperty::encode(has_name_static_property) |
   2823                   HasStaticComputedNames::encode(has_static_computed_names);
   2824   }
   2825 
   2826   int end_position_;
   2827   FeedbackSlot home_object_slot_;
   2828   FeedbackSlot proxy_slot_;
   2829   VariableProxy* class_variable_proxy_;
   2830   Expression* extends_;
   2831   FunctionLiteral* constructor_;
   2832   ZoneList<Property*>* properties_;
   2833 
   2834   class HasNameStaticProperty
   2835       : public BitField<bool, Expression::kNextBitFieldIndex, 1> {};
   2836   class HasStaticComputedNames
   2837       : public BitField<bool, HasNameStaticProperty::kNext, 1> {};
   2838 };
   2839 
   2840 
   2841 class NativeFunctionLiteral final : public Expression {
   2842  public:
   2843   Handle<String> name() const { return name_->string(); }
   2844   v8::Extension* extension() const { return extension_; }
   2845   FeedbackSlot LiteralFeedbackSlot() const { return literal_feedback_slot_; }
   2846 
   2847   void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
   2848                            FeedbackSlotCache* cache) {
   2849     // TODO(mvstanton): The FeedbackSlotCache can be adapted
   2850     // to always return the same slot for this case.
   2851     literal_feedback_slot_ = spec->AddCreateClosureSlot();
   2852   }
   2853 
   2854  private:
   2855   friend class AstNodeFactory;
   2856 
   2857   NativeFunctionLiteral(const AstRawString* name, v8::Extension* extension,
   2858                         int pos)
   2859       : Expression(pos, kNativeFunctionLiteral),
   2860         name_(name),
   2861         extension_(extension) {}
   2862 
   2863   const AstRawString* name_;
   2864   v8::Extension* extension_;
   2865   FeedbackSlot literal_feedback_slot_;
   2866 };
   2867 
   2868 
   2869 class ThisFunction final : public Expression {
   2870  private:
   2871   friend class AstNodeFactory;
   2872   explicit ThisFunction(int pos) : Expression(pos, kThisFunction) {}
   2873 };
   2874 
   2875 
   2876 class SuperPropertyReference final : public Expression {
   2877  public:
   2878   VariableProxy* this_var() const { return this_var_; }
   2879   void set_this_var(VariableProxy* v) { this_var_ = v; }
   2880   Expression* home_object() const { return home_object_; }
   2881   void set_home_object(Expression* e) { home_object_ = e; }
   2882 
   2883  private:
   2884   friend class AstNodeFactory;
   2885 
   2886   SuperPropertyReference(VariableProxy* this_var, Expression* home_object,
   2887                          int pos)
   2888       : Expression(pos, kSuperPropertyReference),
   2889         this_var_(this_var),
   2890         home_object_(home_object) {
   2891     DCHECK(this_var->is_this());
   2892     DCHECK(home_object->IsProperty());
   2893   }
   2894 
   2895   VariableProxy* this_var_;
   2896   Expression* home_object_;
   2897 };
   2898 
   2899 
   2900 class SuperCallReference final : public Expression {
   2901  public:
   2902   VariableProxy* this_var() const { return this_var_; }
   2903   void set_this_var(VariableProxy* v) { this_var_ = v; }
   2904   VariableProxy* new_target_var() const { return new_target_var_; }
   2905   void set_new_target_var(VariableProxy* v) { new_target_var_ = v; }
   2906   VariableProxy* this_function_var() const { return this_function_var_; }
   2907   void set_this_function_var(VariableProxy* v) { this_function_var_ = v; }
   2908 
   2909  private:
   2910   friend class AstNodeFactory;
   2911 
   2912   SuperCallReference(VariableProxy* this_var, VariableProxy* new_target_var,
   2913                      VariableProxy* this_function_var, int pos)
   2914       : Expression(pos, kSuperCallReference),
   2915         this_var_(this_var),
   2916         new_target_var_(new_target_var),
   2917         this_function_var_(this_function_var) {
   2918     DCHECK(this_var->is_this());
   2919     DCHECK(new_target_var->raw_name()->IsOneByteEqualTo(".new.target"));
   2920     DCHECK(this_function_var->raw_name()->IsOneByteEqualTo(".this_function"));
   2921   }
   2922 
   2923   VariableProxy* this_var_;
   2924   VariableProxy* new_target_var_;
   2925   VariableProxy* this_function_var_;
   2926 };
   2927 
   2928 
   2929 // This class is produced when parsing the () in arrow functions without any
   2930 // arguments and is not actually a valid expression.
   2931 class EmptyParentheses final : public Expression {
   2932  private:
   2933   friend class AstNodeFactory;
   2934 
   2935   explicit EmptyParentheses(int pos) : Expression(pos, kEmptyParentheses) {}
   2936 };
   2937 
   2938 // Represents the spec operation `GetIterator()`
   2939 // (defined at https://tc39.github.io/ecma262/#sec-getiterator). Ignition
   2940 // desugars this into a LoadIC / JSLoadNamed, CallIC, and a type-check to
   2941 // validate return value of the Symbol.iterator() call.
   2942 enum class IteratorType { kNormal, kAsync };
   2943 class GetIterator final : public Expression {
   2944  public:
   2945   IteratorType hint() const { return hint_; }
   2946 
   2947   Expression* iterable() const { return iterable_; }
   2948   void set_iterable(Expression* iterable) { iterable_ = iterable; }
   2949 
   2950   static int num_ids() { return parent_num_ids(); }
   2951 
   2952   void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
   2953                            FeedbackSlotCache* cache) {
   2954     iterator_property_feedback_slot_ = spec->AddLoadICSlot();
   2955     iterator_call_feedback_slot_ = spec->AddCallICSlot();
   2956     if (hint() == IteratorType::kAsync) {
   2957       async_iterator_property_feedback_slot_ = spec->AddLoadICSlot();
   2958       async_iterator_call_feedback_slot_ = spec->AddCallICSlot();
   2959     }
   2960   }
   2961 
   2962   FeedbackSlot IteratorPropertyFeedbackSlot() const {
   2963     return iterator_property_feedback_slot_;
   2964   }
   2965 
   2966   FeedbackSlot IteratorCallFeedbackSlot() const {
   2967     return iterator_call_feedback_slot_;
   2968   }
   2969 
   2970   FeedbackSlot AsyncIteratorPropertyFeedbackSlot() const {
   2971     return async_iterator_property_feedback_slot_;
   2972   }
   2973 
   2974   FeedbackSlot AsyncIteratorCallFeedbackSlot() const {
   2975     return async_iterator_call_feedback_slot_;
   2976   }
   2977 
   2978  private:
   2979   friend class AstNodeFactory;
   2980 
   2981   explicit GetIterator(Expression* iterable, IteratorType hint, int pos)
   2982       : Expression(pos, kGetIterator), hint_(hint), iterable_(iterable) {}
   2983 
   2984   IteratorType hint_;
   2985   Expression* iterable_;
   2986   FeedbackSlot iterator_property_feedback_slot_;
   2987   FeedbackSlot iterator_call_feedback_slot_;
   2988   FeedbackSlot async_iterator_property_feedback_slot_;
   2989   FeedbackSlot async_iterator_call_feedback_slot_;
   2990 };
   2991 
   2992 // ----------------------------------------------------------------------------
   2993 // Basic visitor
   2994 // Sub-class should parametrize AstVisitor with itself, e.g.:
   2995 //   class SpecificVisitor : public AstVisitor<SpecificVisitor> { ... }
   2996 
   2997 template <class Subclass>
   2998 class AstVisitor BASE_EMBEDDED {
   2999  public:
   3000   void Visit(AstNode* node) { impl()->Visit(node); }
   3001 
   3002   void VisitDeclarations(Declaration::List* declarations) {
   3003     for (Declaration* decl : *declarations) Visit(decl);
   3004   }
   3005 
   3006   void VisitStatements(ZoneList<Statement*>* statements) {
   3007     for (int i = 0; i < statements->length(); i++) {
   3008       Statement* stmt = statements->at(i);
   3009       Visit(stmt);
   3010       if (stmt->IsJump()) break;
   3011     }
   3012   }
   3013 
   3014   void VisitExpressions(ZoneList<Expression*>* expressions) {
   3015     for (int i = 0; i < expressions->length(); i++) {
   3016       // The variable statement visiting code may pass NULL expressions
   3017       // to this code. Maybe this should be handled by introducing an
   3018       // undefined expression or literal?  Revisit this code if this
   3019       // changes
   3020       Expression* expression = expressions->at(i);
   3021       if (expression != NULL) Visit(expression);
   3022     }
   3023   }
   3024 
   3025  protected:
   3026   Subclass* impl() { return static_cast<Subclass*>(this); }
   3027 };
   3028 
   3029 #define GENERATE_VISIT_CASE(NodeType)                                   \
   3030   case AstNode::k##NodeType:                                            \
   3031     return this->impl()->Visit##NodeType(static_cast<NodeType*>(node));
   3032 
   3033 #define GENERATE_AST_VISITOR_SWITCH()  \
   3034   switch (node->node_type()) {         \
   3035     AST_NODE_LIST(GENERATE_VISIT_CASE) \
   3036   }
   3037 
   3038 #define DEFINE_AST_VISITOR_SUBCLASS_MEMBERS()               \
   3039  public:                                                    \
   3040   void VisitNoStackOverflowCheck(AstNode* node) {           \
   3041     GENERATE_AST_VISITOR_SWITCH()                           \
   3042   }                                                         \
   3043                                                             \
   3044   void Visit(AstNode* node) {                               \
   3045     if (CheckStackOverflow()) return;                       \
   3046     VisitNoStackOverflowCheck(node);                        \
   3047   }                                                         \
   3048                                                             \
   3049   void SetStackOverflow() { stack_overflow_ = true; }       \
   3050   void ClearStackOverflow() { stack_overflow_ = false; }    \
   3051   bool HasStackOverflow() const { return stack_overflow_; } \
   3052                                                             \
   3053   bool CheckStackOverflow() {                               \
   3054     if (stack_overflow_) return true;                       \
   3055     if (GetCurrentStackPosition() < stack_limit_) {         \
   3056       stack_overflow_ = true;                               \
   3057       return true;                                          \
   3058     }                                                       \
   3059     return false;                                           \
   3060   }                                                         \
   3061                                                             \
   3062  private:                                                   \
   3063   void InitializeAstVisitor(Isolate* isolate) {             \
   3064     stack_limit_ = isolate->stack_guard()->real_climit();   \
   3065     stack_overflow_ = false;                                \
   3066   }                                                         \
   3067                                                             \
   3068   void InitializeAstVisitor(uintptr_t stack_limit) {        \
   3069     stack_limit_ = stack_limit;                             \
   3070     stack_overflow_ = false;                                \
   3071   }                                                         \
   3072                                                             \
   3073   uintptr_t stack_limit_;                                   \
   3074   bool stack_overflow_
   3075 
   3076 #define DEFINE_AST_VISITOR_MEMBERS_WITHOUT_STACKOVERFLOW()    \
   3077  public:                                                      \
   3078   void Visit(AstNode* node) { GENERATE_AST_VISITOR_SWITCH() } \
   3079                                                               \
   3080  private:
   3081 
   3082 #define DEFINE_AST_REWRITER_SUBCLASS_MEMBERS()        \
   3083  public:                                              \
   3084   AstNode* Rewrite(AstNode* node) {                   \
   3085     DCHECK_NULL(replacement_);                        \
   3086     DCHECK_NOT_NULL(node);                            \
   3087     Visit(node);                                      \
   3088     if (HasStackOverflow()) return node;              \
   3089     if (replacement_ == nullptr) return node;         \
   3090     AstNode* result = replacement_;                   \
   3091     replacement_ = nullptr;                           \
   3092     return result;                                    \
   3093   }                                                   \
   3094                                                       \
   3095  private:                                             \
   3096   void InitializeAstRewriter(Isolate* isolate) {      \
   3097     InitializeAstVisitor(isolate);                    \
   3098     replacement_ = nullptr;                           \
   3099   }                                                   \
   3100                                                       \
   3101   void InitializeAstRewriter(uintptr_t stack_limit) { \
   3102     InitializeAstVisitor(stack_limit);                \
   3103     replacement_ = nullptr;                           \
   3104   }                                                   \
   3105                                                       \
   3106   DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();              \
   3107                                                       \
   3108  protected:                                           \
   3109   AstNode* replacement_
   3110 // Generic macro for rewriting things; `GET` is the expression to be
   3111 // rewritten; `SET` is a command that should do the rewriting, i.e.
   3112 // something sensible with the variable called `replacement`.
   3113 #define AST_REWRITE(Type, GET, SET)                            \
   3114   do {                                                         \
   3115     DCHECK(!HasStackOverflow());                               \
   3116     DCHECK_NULL(replacement_);                                 \
   3117     Visit(GET);                                                \
   3118     if (HasStackOverflow()) return;                            \
   3119     if (replacement_ == nullptr) break;                        \
   3120     Type* replacement = reinterpret_cast<Type*>(replacement_); \
   3121     do {                                                       \
   3122       SET;                                                     \
   3123     } while (false);                                           \
   3124     replacement_ = nullptr;                                    \
   3125   } while (false)
   3126 
   3127 // Macro for rewriting object properties; it assumes that `object` has
   3128 // `property` with a public getter and setter.
   3129 #define AST_REWRITE_PROPERTY(Type, object, property)                        \
   3130   do {                                                                      \
   3131     auto _obj = (object);                                                   \
   3132     AST_REWRITE(Type, _obj->property(), _obj->set_##property(replacement)); \
   3133   } while (false)
   3134 
   3135 // Macro for rewriting list elements; it assumes that `list` has methods
   3136 // `at` and `Set`.
   3137 #define AST_REWRITE_LIST_ELEMENT(Type, list, index)                        \
   3138   do {                                                                     \
   3139     auto _list = (list);                                                   \
   3140     auto _index = (index);                                                 \
   3141     AST_REWRITE(Type, _list->at(_index), _list->Set(_index, replacement)); \
   3142   } while (false)
   3143 
   3144 
   3145 // ----------------------------------------------------------------------------
   3146 // AstNode factory
   3147 
   3148 class AstNodeFactory final BASE_EMBEDDED {
   3149  public:
   3150   explicit AstNodeFactory(AstValueFactory* ast_value_factory)
   3151       : zone_(nullptr), ast_value_factory_(ast_value_factory) {
   3152     if (ast_value_factory != nullptr) {
   3153       zone_ = ast_value_factory->zone();
   3154     }
   3155   }
   3156 
   3157   AstValueFactory* ast_value_factory() const { return ast_value_factory_; }
   3158   void set_ast_value_factory(AstValueFactory* ast_value_factory) {
   3159     ast_value_factory_ = ast_value_factory;
   3160     zone_ = ast_value_factory->zone();
   3161   }
   3162 
   3163   VariableDeclaration* NewVariableDeclaration(VariableProxy* proxy,
   3164                                               Scope* scope, int pos) {
   3165     return new (zone_) VariableDeclaration(proxy, scope, pos);
   3166   }
   3167 
   3168   FunctionDeclaration* NewFunctionDeclaration(VariableProxy* proxy,
   3169                                               FunctionLiteral* fun,
   3170                                               Scope* scope, int pos) {
   3171     return new (zone_) FunctionDeclaration(proxy, fun, scope, pos);
   3172   }
   3173 
   3174   Block* NewBlock(ZoneList<const AstRawString*>* labels, int capacity,
   3175                   bool ignore_completion_value, int pos) {
   3176     return new (zone_)
   3177         Block(zone_, labels, capacity, ignore_completion_value, pos);
   3178   }
   3179 
   3180 #define STATEMENT_WITH_LABELS(NodeType)                                     \
   3181   NodeType* New##NodeType(ZoneList<const AstRawString*>* labels, int pos) { \
   3182     return new (zone_) NodeType(labels, pos);                               \
   3183   }
   3184   STATEMENT_WITH_LABELS(DoWhileStatement)
   3185   STATEMENT_WITH_LABELS(WhileStatement)
   3186   STATEMENT_WITH_LABELS(ForStatement)
   3187   STATEMENT_WITH_LABELS(SwitchStatement)
   3188 #undef STATEMENT_WITH_LABELS
   3189 
   3190   ForEachStatement* NewForEachStatement(ForEachStatement::VisitMode visit_mode,
   3191                                         ZoneList<const AstRawString*>* labels,
   3192                                         int pos) {
   3193     switch (visit_mode) {
   3194       case ForEachStatement::ENUMERATE: {
   3195         return new (zone_) ForInStatement(labels, pos);
   3196       }
   3197       case ForEachStatement::ITERATE: {
   3198         return new (zone_) ForOfStatement(labels, pos);
   3199       }
   3200     }
   3201     UNREACHABLE();
   3202     return NULL;
   3203   }
   3204 
   3205   ForOfStatement* NewForOfStatement(ZoneList<const AstRawString*>* labels,
   3206                                     int pos) {
   3207     return new (zone_) ForOfStatement(labels, pos);
   3208   }
   3209 
   3210   ExpressionStatement* NewExpressionStatement(Expression* expression, int pos) {
   3211     return new (zone_) ExpressionStatement(expression, pos);
   3212   }
   3213 
   3214   ContinueStatement* NewContinueStatement(IterationStatement* target, int pos) {
   3215     return new (zone_) ContinueStatement(target, pos);
   3216   }
   3217 
   3218   BreakStatement* NewBreakStatement(BreakableStatement* target, int pos) {
   3219     return new (zone_) BreakStatement(target, pos);
   3220   }
   3221 
   3222   ReturnStatement* NewReturnStatement(Expression* expression, int pos) {
   3223     return new (zone_)
   3224         ReturnStatement(expression, ReturnStatement::kNormal, pos);
   3225   }
   3226 
   3227   ReturnStatement* NewAsyncReturnStatement(Expression* expression, int pos) {
   3228     return new (zone_)
   3229         ReturnStatement(expression, ReturnStatement::kAsyncReturn, pos);
   3230   }
   3231 
   3232   WithStatement* NewWithStatement(Scope* scope,
   3233                                   Expression* expression,
   3234                                   Statement* statement,
   3235                                   int pos) {
   3236     return new (zone_) WithStatement(scope, expression, statement, pos);
   3237   }
   3238 
   3239   IfStatement* NewIfStatement(Expression* condition,
   3240                               Statement* then_statement,
   3241                               Statement* else_statement,
   3242                               int pos) {
   3243     return new (zone_)
   3244         IfStatement(condition, then_statement, else_statement, pos);
   3245   }
   3246 
   3247   TryCatchStatement* NewTryCatchStatement(Block* try_block, Scope* scope,
   3248                                           Variable* variable,
   3249                                           Block* catch_block, int pos) {
   3250     return new (zone_) TryCatchStatement(
   3251         try_block, scope, variable, catch_block, HandlerTable::CAUGHT, pos);
   3252   }
   3253 
   3254   TryCatchStatement* NewTryCatchStatementForReThrow(Block* try_block,
   3255                                                     Scope* scope,
   3256                                                     Variable* variable,
   3257                                                     Block* catch_block,
   3258                                                     int pos) {
   3259     return new (zone_) TryCatchStatement(
   3260         try_block, scope, variable, catch_block, HandlerTable::UNCAUGHT, pos);
   3261   }
   3262 
   3263   TryCatchStatement* NewTryCatchStatementForDesugaring(Block* try_block,
   3264                                                        Scope* scope,
   3265                                                        Variable* variable,
   3266                                                        Block* catch_block,
   3267                                                        int pos) {
   3268     return new (zone_) TryCatchStatement(
   3269         try_block, scope, variable, catch_block, HandlerTable::DESUGARING, pos);
   3270   }
   3271 
   3272   TryCatchStatement* NewTryCatchStatementForAsyncAwait(Block* try_block,
   3273                                                        Scope* scope,
   3274                                                        Variable* variable,
   3275                                                        Block* catch_block,
   3276                                                        int pos) {
   3277     return new (zone_)
   3278         TryCatchStatement(try_block, scope, variable, catch_block,
   3279                           HandlerTable::ASYNC_AWAIT, pos);
   3280   }
   3281 
   3282   TryFinallyStatement* NewTryFinallyStatement(Block* try_block,
   3283                                               Block* finally_block, int pos) {
   3284     return new (zone_) TryFinallyStatement(try_block, finally_block, pos);
   3285   }
   3286 
   3287   DebuggerStatement* NewDebuggerStatement(int pos) {
   3288     return new (zone_) DebuggerStatement(pos);
   3289   }
   3290 
   3291   EmptyStatement* NewEmptyStatement(int pos) {
   3292     return new (zone_) EmptyStatement(pos);
   3293   }
   3294 
   3295   SloppyBlockFunctionStatement* NewSloppyBlockFunctionStatement() {
   3296     return new (zone_)
   3297         SloppyBlockFunctionStatement(NewEmptyStatement(kNoSourcePosition));
   3298   }
   3299 
   3300   CaseClause* NewCaseClause(
   3301       Expression* label, ZoneList<Statement*>* statements, int pos) {
   3302     return new (zone_) CaseClause(label, statements, pos);
   3303   }
   3304 
   3305   Literal* NewStringLiteral(const AstRawString* string, int pos) {
   3306     return new (zone_) Literal(ast_value_factory_->NewString(string), pos);
   3307   }
   3308 
   3309   // A JavaScript symbol (ECMA-262 edition 6).
   3310   Literal* NewSymbolLiteral(AstSymbol symbol, int pos) {
   3311     return new (zone_) Literal(ast_value_factory_->NewSymbol(symbol), pos);
   3312   }
   3313 
   3314   Literal* NewNumberLiteral(double number, int pos, bool with_dot = false) {
   3315     return new (zone_)
   3316         Literal(ast_value_factory_->NewNumber(number, with_dot), pos);
   3317   }
   3318 
   3319   Literal* NewSmiLiteral(uint32_t number, int pos) {
   3320     return new (zone_) Literal(ast_value_factory_->NewSmi(number), pos);
   3321   }
   3322 
   3323   Literal* NewBooleanLiteral(bool b, int pos) {
   3324     return new (zone_) Literal(ast_value_factory_->NewBoolean(b), pos);
   3325   }
   3326 
   3327   Literal* NewNullLiteral(int pos) {
   3328     return new (zone_) Literal(ast_value_factory_->NewNull(), pos);
   3329   }
   3330 
   3331   Literal* NewUndefinedLiteral(int pos) {
   3332     return new (zone_) Literal(ast_value_factory_->NewUndefined(), pos);
   3333   }
   3334 
   3335   Literal* NewTheHoleLiteral(int pos) {
   3336     return new (zone_) Literal(ast_value_factory_->NewTheHole(), pos);
   3337   }
   3338 
   3339   ObjectLiteral* NewObjectLiteral(
   3340       ZoneList<ObjectLiteral::Property*>* properties,
   3341       uint32_t boilerplate_properties, int pos, bool has_rest_property) {
   3342     return new (zone_) ObjectLiteral(properties, boilerplate_properties, pos,
   3343                                      has_rest_property);
   3344   }
   3345 
   3346   ObjectLiteral::Property* NewObjectLiteralProperty(
   3347       Expression* key, Expression* value, ObjectLiteralProperty::Kind kind,
   3348       bool is_computed_name) {
   3349     return new (zone_)
   3350         ObjectLiteral::Property(key, value, kind, is_computed_name);
   3351   }
   3352 
   3353   ObjectLiteral::Property* NewObjectLiteralProperty(Expression* key,
   3354                                                     Expression* value,
   3355                                                     bool is_computed_name) {
   3356     return new (zone_) ObjectLiteral::Property(ast_value_factory_, key, value,
   3357                                                is_computed_name);
   3358   }
   3359 
   3360   RegExpLiteral* NewRegExpLiteral(const AstRawString* pattern, int flags,
   3361                                   int pos) {
   3362     return new (zone_) RegExpLiteral(pattern, flags, pos);
   3363   }
   3364 
   3365   ArrayLiteral* NewArrayLiteral(ZoneList<Expression*>* values,
   3366                                 int pos) {
   3367     return new (zone_) ArrayLiteral(values, -1, pos);
   3368   }
   3369 
   3370   ArrayLiteral* NewArrayLiteral(ZoneList<Expression*>* values,
   3371                                 int first_spread_index, int pos) {
   3372     return new (zone_) ArrayLiteral(values, first_spread_index, pos);
   3373   }
   3374 
   3375   VariableProxy* NewVariableProxy(Variable* var,
   3376                                   int start_position = kNoSourcePosition) {
   3377     return new (zone_) VariableProxy(var, start_position);
   3378   }
   3379 
   3380   VariableProxy* NewVariableProxy(const AstRawString* name,
   3381                                   VariableKind variable_kind,
   3382                                   int start_position = kNoSourcePosition) {
   3383     DCHECK_NOT_NULL(name);
   3384     return new (zone_) VariableProxy(name, variable_kind, start_position);
   3385   }
   3386 
   3387   // Recreates the VariableProxy in this Zone.
   3388   VariableProxy* CopyVariableProxy(VariableProxy* proxy) {
   3389     return new (zone_) VariableProxy(proxy);
   3390   }
   3391 
   3392   Property* NewProperty(Expression* obj, Expression* key, int pos) {
   3393     return new (zone_) Property(obj, key, pos);
   3394   }
   3395 
   3396   Call* NewCall(Expression* expression, ZoneList<Expression*>* arguments,
   3397                 int pos, Call::PossiblyEval possibly_eval = Call::NOT_EVAL) {
   3398     return new (zone_) Call(expression, arguments, pos, possibly_eval);
   3399   }
   3400 
   3401   CallNew* NewCallNew(Expression* expression,
   3402                       ZoneList<Expression*>* arguments,
   3403                       int pos) {
   3404     return new (zone_) CallNew(expression, arguments, pos);
   3405   }
   3406 
   3407   CallRuntime* NewCallRuntime(Runtime::FunctionId id,
   3408                               ZoneList<Expression*>* arguments, int pos) {
   3409     return new (zone_) CallRuntime(Runtime::FunctionForId(id), arguments, pos);
   3410   }
   3411 
   3412   CallRuntime* NewCallRuntime(const Runtime::Function* function,
   3413                               ZoneList<Expression*>* arguments, int pos) {
   3414     return new (zone_) CallRuntime(function, arguments, pos);
   3415   }
   3416 
   3417   CallRuntime* NewCallRuntime(int context_index,
   3418                               ZoneList<Expression*>* arguments, int pos) {
   3419     return new (zone_) CallRuntime(context_index, arguments, pos);
   3420   }
   3421 
   3422   UnaryOperation* NewUnaryOperation(Token::Value op,
   3423                                     Expression* expression,
   3424                                     int pos) {
   3425     return new (zone_) UnaryOperation(op, expression, pos);
   3426   }
   3427 
   3428   BinaryOperation* NewBinaryOperation(Token::Value op,
   3429                                       Expression* left,
   3430                                       Expression* right,
   3431                                       int pos) {
   3432     return new (zone_) BinaryOperation(op, left, right, pos);
   3433   }
   3434 
   3435   CountOperation* NewCountOperation(Token::Value op,
   3436                                     bool is_prefix,
   3437                                     Expression* expr,
   3438                                     int pos) {
   3439     return new (zone_) CountOperation(op, is_prefix, expr, pos);
   3440   }
   3441 
   3442   CompareOperation* NewCompareOperation(Token::Value op,
   3443                                         Expression* left,
   3444                                         Expression* right,
   3445                                         int pos) {
   3446     return new (zone_) CompareOperation(op, left, right, pos);
   3447   }
   3448 
   3449   Spread* NewSpread(Expression* expression, int pos, int expr_pos) {
   3450     return new (zone_) Spread(expression, pos, expr_pos);
   3451   }
   3452 
   3453   Conditional* NewConditional(Expression* condition,
   3454                               Expression* then_expression,
   3455                               Expression* else_expression,
   3456                               int position) {
   3457     return new (zone_)
   3458         Conditional(condition, then_expression, else_expression, position);
   3459   }
   3460 
   3461   RewritableExpression* NewRewritableExpression(Expression* expression) {
   3462     DCHECK_NOT_NULL(expression);
   3463     return new (zone_) RewritableExpression(expression);
   3464   }
   3465 
   3466   Assignment* NewAssignment(Token::Value op,
   3467                             Expression* target,
   3468                             Expression* value,
   3469                             int pos) {
   3470     DCHECK(Token::IsAssignmentOp(op));
   3471 
   3472     if (op != Token::INIT && target->IsVariableProxy()) {
   3473       target->AsVariableProxy()->set_is_assigned();
   3474     }
   3475 
   3476     Assignment* assign = new (zone_) Assignment(op, target, value, pos);
   3477     if (assign->is_compound()) {
   3478       assign->binary_operation_ =
   3479           NewBinaryOperation(assign->binary_op(), target, value, pos + 1);
   3480     }
   3481     return assign;
   3482   }
   3483 
   3484   Yield* NewYield(Expression* generator_object, Expression* expression, int pos,
   3485                   Yield::OnException on_exception) {
   3486     if (!expression) expression = NewUndefinedLiteral(pos);
   3487     return new (zone_) Yield(generator_object, expression, pos, on_exception);
   3488   }
   3489 
   3490   Throw* NewThrow(Expression* exception, int pos) {
   3491     return new (zone_) Throw(exception, pos);
   3492   }
   3493 
   3494   FunctionLiteral* NewFunctionLiteral(
   3495       const AstRawString* name, DeclarationScope* scope,
   3496       ZoneList<Statement*>* body, int expected_property_count,
   3497       int parameter_count, int function_length,
   3498       FunctionLiteral::ParameterFlag has_duplicate_parameters,
   3499       FunctionLiteral::FunctionType function_type,
   3500       FunctionLiteral::EagerCompileHint eager_compile_hint, int position,
   3501       bool has_braces, int function_literal_id) {
   3502     return new (zone_) FunctionLiteral(
   3503         zone_, name, ast_value_factory_, scope, body, expected_property_count,
   3504         parameter_count, function_length, function_type,
   3505         has_duplicate_parameters, eager_compile_hint, position, has_braces,
   3506         function_literal_id);
   3507   }
   3508 
   3509   // Creates a FunctionLiteral representing a top-level script, the
   3510   // result of an eval (top-level or otherwise), or the result of calling
   3511   // the Function constructor.
   3512   FunctionLiteral* NewScriptOrEvalFunctionLiteral(DeclarationScope* scope,
   3513                                                   ZoneList<Statement*>* body,
   3514                                                   int expected_property_count,
   3515                                                   int parameter_count) {
   3516     return new (zone_) FunctionLiteral(
   3517         zone_, ast_value_factory_->empty_string(), ast_value_factory_, scope,
   3518         body, expected_property_count, parameter_count, parameter_count,
   3519         FunctionLiteral::kAnonymousExpression,
   3520         FunctionLiteral::kNoDuplicateParameters,
   3521         FunctionLiteral::kShouldLazyCompile, 0, true,
   3522         FunctionLiteral::kIdTypeTopLevel);
   3523   }
   3524 
   3525   ClassLiteral::Property* NewClassLiteralProperty(
   3526       Expression* key, Expression* value, ClassLiteralProperty::Kind kind,
   3527       bool is_static, bool is_computed_name) {
   3528     return new (zone_)
   3529         ClassLiteral::Property(key, value, kind, is_static, is_computed_name);
   3530   }
   3531 
   3532   ClassLiteral* NewClassLiteral(VariableProxy* proxy, Expression* extends,
   3533                                 FunctionLiteral* constructor,
   3534                                 ZoneList<ClassLiteral::Property*>* properties,
   3535                                 int start_position, int end_position,
   3536                                 bool has_name_static_property,
   3537                                 bool has_static_computed_names) {
   3538     return new (zone_) ClassLiteral(
   3539         proxy, extends, constructor, properties, start_position, end_position,
   3540         has_name_static_property, has_static_computed_names);
   3541   }
   3542 
   3543   NativeFunctionLiteral* NewNativeFunctionLiteral(const AstRawString* name,
   3544                                                   v8::Extension* extension,
   3545                                                   int pos) {
   3546     return new (zone_) NativeFunctionLiteral(name, extension, pos);
   3547   }
   3548 
   3549   DoExpression* NewDoExpression(Block* block, Variable* result_var, int pos) {
   3550     VariableProxy* result = NewVariableProxy(result_var, pos);
   3551     return new (zone_) DoExpression(block, result, pos);
   3552   }
   3553 
   3554   ThisFunction* NewThisFunction(int pos) {
   3555     return new (zone_) ThisFunction(pos);
   3556   }
   3557 
   3558   SuperPropertyReference* NewSuperPropertyReference(VariableProxy* this_var,
   3559                                                     Expression* home_object,
   3560                                                     int pos) {
   3561     return new (zone_) SuperPropertyReference(this_var, home_object, pos);
   3562   }
   3563 
   3564   SuperCallReference* NewSuperCallReference(VariableProxy* this_var,
   3565                                             VariableProxy* new_target_var,
   3566                                             VariableProxy* this_function_var,
   3567                                             int pos) {
   3568     return new (zone_)
   3569         SuperCallReference(this_var, new_target_var, this_function_var, pos);
   3570   }
   3571 
   3572   EmptyParentheses* NewEmptyParentheses(int pos) {
   3573     return new (zone_) EmptyParentheses(pos);
   3574   }
   3575 
   3576   GetIterator* NewGetIterator(Expression* iterable, IteratorType hint,
   3577                               int pos) {
   3578     return new (zone_) GetIterator(iterable, hint, pos);
   3579   }
   3580 
   3581   Zone* zone() const { return zone_; }
   3582   void set_zone(Zone* zone) { zone_ = zone; }
   3583 
   3584   // Handles use of temporary zones when parsing inner function bodies.
   3585   class BodyScope {
   3586    public:
   3587     BodyScope(AstNodeFactory* factory, Zone* temp_zone, bool use_temp_zone)
   3588         : factory_(factory), prev_zone_(factory->zone_) {
   3589       if (use_temp_zone) {
   3590         factory->zone_ = temp_zone;
   3591       }
   3592     }
   3593 
   3594     void Reset() { factory_->zone_ = prev_zone_; }
   3595     ~BodyScope() { Reset(); }
   3596 
   3597    private:
   3598     AstNodeFactory* factory_;
   3599     Zone* prev_zone_;
   3600   };
   3601 
   3602  private:
   3603   // This zone may be deallocated upon returning from parsing a function body
   3604   // which we can guarantee is not going to be compiled or have its AST
   3605   // inspected.
   3606   // See ParseFunctionLiteral in parser.cc for preconditions.
   3607   Zone* zone_;
   3608   AstValueFactory* ast_value_factory_;
   3609 };
   3610 
   3611 
   3612 // Type testing & conversion functions overridden by concrete subclasses.
   3613 // Inline functions for AstNode.
   3614 
   3615 #define DECLARE_NODE_FUNCTIONS(type)                                          \
   3616   bool AstNode::Is##type() const {                                            \
   3617     NodeType mine = node_type();                                              \
   3618     if (mine == AstNode::kRewritableExpression &&                             \
   3619         AstNode::k##type != AstNode::kRewritableExpression)                   \
   3620       mine = reinterpret_cast<const RewritableExpression*>(this)              \
   3621                  ->expression()                                               \
   3622                  ->node_type();                                               \
   3623     return mine == AstNode::k##type;                                          \
   3624   }                                                                           \
   3625   type* AstNode::As##type() {                                                 \
   3626     NodeType mine = node_type();                                              \
   3627     AstNode* result = this;                                                   \
   3628     if (mine == AstNode::kRewritableExpression &&                             \
   3629         AstNode::k##type != AstNode::kRewritableExpression) {                 \
   3630       result =                                                                \
   3631           reinterpret_cast<const RewritableExpression*>(this)->expression();  \
   3632       mine = result->node_type();                                             \
   3633     }                                                                         \
   3634     return mine == AstNode::k##type ? reinterpret_cast<type*>(result) : NULL; \
   3635   }                                                                           \
   3636   const type* AstNode::As##type() const {                                     \
   3637     NodeType mine = node_type();                                              \
   3638     const AstNode* result = this;                                             \
   3639     if (mine == AstNode::kRewritableExpression &&                             \
   3640         AstNode::k##type != AstNode::kRewritableExpression) {                 \
   3641       result =                                                                \
   3642           reinterpret_cast<const RewritableExpression*>(this)->expression();  \
   3643       mine = result->node_type();                                             \
   3644     }                                                                         \
   3645     return mine == AstNode::k##type ? reinterpret_cast<const type*>(result)   \
   3646                                     : NULL;                                   \
   3647   }
   3648 AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
   3649 #undef DECLARE_NODE_FUNCTIONS
   3650 
   3651 
   3652 }  // namespace internal
   3653 }  // namespace v8
   3654 
   3655 #endif  // V8_AST_AST_H_
   3656