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