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