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