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