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