Home | History | Annotate | Download | only in src
      1 // Copyright 2011 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 "execution.h"
     32 #include "factory.h"
     33 #include "jsregexp.h"
     34 #include "runtime.h"
     35 #include "token.h"
     36 #include "variables.h"
     37 
     38 namespace v8 {
     39 namespace internal {
     40 
     41 // The abstract syntax tree is an intermediate, light-weight
     42 // representation of the parsed JavaScript code suitable for
     43 // compilation to native code.
     44 
     45 // Nodes are allocated in a separate zone, which allows faster
     46 // allocation and constant-time deallocation of the entire syntax
     47 // tree.
     48 
     49 
     50 // ----------------------------------------------------------------------------
     51 // Nodes of the abstract syntax tree. Only concrete classes are
     52 // enumerated here.
     53 
     54 #define STATEMENT_NODE_LIST(V)                  \
     55   V(Block)                                      \
     56   V(ExpressionStatement)                        \
     57   V(EmptyStatement)                             \
     58   V(IfStatement)                                \
     59   V(ContinueStatement)                          \
     60   V(BreakStatement)                             \
     61   V(ReturnStatement)                            \
     62   V(WithEnterStatement)                         \
     63   V(WithExitStatement)                          \
     64   V(SwitchStatement)                            \
     65   V(DoWhileStatement)                           \
     66   V(WhileStatement)                             \
     67   V(ForStatement)                               \
     68   V(ForInStatement)                             \
     69   V(TryCatchStatement)                          \
     70   V(TryFinallyStatement)                        \
     71   V(DebuggerStatement)
     72 
     73 #define EXPRESSION_NODE_LIST(V)                 \
     74   V(FunctionLiteral)                            \
     75   V(SharedFunctionInfoLiteral)                  \
     76   V(Conditional)                                \
     77   V(VariableProxy)                              \
     78   V(Literal)                                    \
     79   V(RegExpLiteral)                              \
     80   V(ObjectLiteral)                              \
     81   V(ArrayLiteral)                               \
     82   V(CatchExtensionObject)                       \
     83   V(Assignment)                                 \
     84   V(Throw)                                      \
     85   V(Property)                                   \
     86   V(Call)                                       \
     87   V(CallNew)                                    \
     88   V(CallRuntime)                                \
     89   V(UnaryOperation)                             \
     90   V(CountOperation)                             \
     91   V(BinaryOperation)                            \
     92   V(CompareOperation)                           \
     93   V(CompareToNull)                              \
     94   V(ThisFunction)
     95 
     96 #define AST_NODE_LIST(V)                        \
     97   V(Declaration)                                \
     98   STATEMENT_NODE_LIST(V)                        \
     99   EXPRESSION_NODE_LIST(V)
    100 
    101 // Forward declarations
    102 class BitVector;
    103 class DefinitionInfo;
    104 class MaterializedLiteral;
    105 class TargetCollector;
    106 class TypeFeedbackOracle;
    107 
    108 #define DEF_FORWARD_DECLARATION(type) class type;
    109 AST_NODE_LIST(DEF_FORWARD_DECLARATION)
    110 #undef DEF_FORWARD_DECLARATION
    111 
    112 
    113 // Typedef only introduced to avoid unreadable code.
    114 // Please do appreciate the required space in "> >".
    115 typedef ZoneList<Handle<String> > ZoneStringList;
    116 typedef ZoneList<Handle<Object> > ZoneObjectList;
    117 
    118 
    119 #define DECLARE_NODE_TYPE(type)                                         \
    120   virtual void Accept(AstVisitor* v);                                   \
    121   virtual AstNode::Type node_type() const { return AstNode::k##type; }  \
    122   virtual type* As##type() { return this; }
    123 
    124 
    125 class AstNode: public ZoneObject {
    126  public:
    127 #define DECLARE_TYPE_ENUM(type) k##type,
    128   enum Type {
    129     AST_NODE_LIST(DECLARE_TYPE_ENUM)
    130     kInvalid = -1
    131   };
    132 #undef DECLARE_TYPE_ENUM
    133 
    134   static const int kNoNumber = -1;
    135   static const int kFunctionEntryId = 2;  // Using 0 could disguise errors.
    136 
    137   AstNode() : id_(GetNextId()) {
    138     Isolate* isolate = Isolate::Current();
    139     isolate->set_ast_node_count(isolate->ast_node_count() + 1);
    140   }
    141 
    142   virtual ~AstNode() { }
    143 
    144   virtual void Accept(AstVisitor* v) = 0;
    145   virtual Type node_type() const { return kInvalid; }
    146 
    147   // Type testing & conversion functions overridden by concrete subclasses.
    148 #define DECLARE_NODE_FUNCTIONS(type)                  \
    149   virtual type* As##type() { return NULL; }
    150   AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
    151 #undef DECLARE_NODE_FUNCTIONS
    152 
    153   virtual Statement* AsStatement() { return NULL; }
    154   virtual Expression* AsExpression() { return NULL; }
    155   virtual TargetCollector* AsTargetCollector() { return NULL; }
    156   virtual BreakableStatement* AsBreakableStatement() { return NULL; }
    157   virtual IterationStatement* AsIterationStatement() { return NULL; }
    158   virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; }
    159   virtual Slot* AsSlot() { return NULL; }
    160 
    161   // True if the node is simple enough for us to inline calls containing it.
    162   virtual bool IsInlineable() const = 0;
    163 
    164   static int Count() { return Isolate::Current()->ast_node_count(); }
    165   static void ResetIds() { Isolate::Current()->set_ast_node_id(0); }
    166   unsigned id() const { return id_; }
    167 
    168  protected:
    169   static unsigned GetNextId() {
    170     Isolate* isolate = Isolate::Current();
    171     unsigned tmp = isolate->ast_node_id();
    172     isolate->set_ast_node_id(tmp + 1);
    173     return tmp;
    174   }
    175   static unsigned ReserveIdRange(int n) {
    176     Isolate* isolate = Isolate::Current();
    177     unsigned tmp = isolate->ast_node_id();
    178     isolate->set_ast_node_id(tmp + n);
    179     return tmp;
    180   }
    181 
    182  private:
    183   unsigned id_;
    184 
    185   friend class CaseClause;  // Generates AST IDs.
    186 };
    187 
    188 
    189 class Statement: public AstNode {
    190  public:
    191   Statement() : statement_pos_(RelocInfo::kNoPosition) {}
    192 
    193   virtual Statement* AsStatement()  { return this; }
    194 
    195   virtual Assignment* StatementAsSimpleAssignment() { return NULL; }
    196   virtual CountOperation* StatementAsCountOperation() { return NULL; }
    197 
    198   bool IsEmpty() { return AsEmptyStatement() != NULL; }
    199 
    200   void set_statement_pos(int statement_pos) { statement_pos_ = statement_pos; }
    201   int statement_pos() const { return statement_pos_; }
    202 
    203  private:
    204   int statement_pos_;
    205 };
    206 
    207 
    208 class Expression: public AstNode {
    209  public:
    210   enum Context {
    211     // Not assigned a context yet, or else will not be visited during
    212     // code generation.
    213     kUninitialized,
    214     // Evaluated for its side effects.
    215     kEffect,
    216     // Evaluated for its value (and side effects).
    217     kValue,
    218     // Evaluated for control flow (and side effects).
    219     kTest
    220   };
    221 
    222   Expression() {}
    223 
    224   virtual int position() const {
    225     UNREACHABLE();
    226     return 0;
    227   }
    228 
    229   virtual Expression* AsExpression()  { return this; }
    230 
    231   virtual bool IsTrivial() { return false; }
    232   virtual bool IsValidLeftHandSide() { return false; }
    233 
    234   // Helpers for ToBoolean conversion.
    235   virtual bool ToBooleanIsTrue() { return false; }
    236   virtual bool ToBooleanIsFalse() { return false; }
    237 
    238   // Symbols that cannot be parsed as array indices are considered property
    239   // names.  We do not treat symbols that can be array indexes as property
    240   // names because [] for string objects is handled only by keyed ICs.
    241   virtual bool IsPropertyName() { return false; }
    242 
    243   // Mark the expression as being compiled as an expression
    244   // statement. This is used to transform postfix increments to
    245   // (faster) prefix increments.
    246   virtual void MarkAsStatement() { /* do nothing */ }
    247 
    248   // True iff the result can be safely overwritten (to avoid allocation).
    249   // False for operations that can return one of their operands.
    250   virtual bool ResultOverwriteAllowed() { return false; }
    251 
    252   // True iff the expression is a literal represented as a smi.
    253   virtual bool IsSmiLiteral() { return false; }
    254 
    255   // Type feedback information for assignments and properties.
    256   virtual bool IsMonomorphic() {
    257     UNREACHABLE();
    258     return false;
    259   }
    260   virtual bool IsArrayLength() {
    261     UNREACHABLE();
    262     return false;
    263   }
    264   virtual ZoneMapList* GetReceiverTypes() {
    265     UNREACHABLE();
    266     return NULL;
    267   }
    268   virtual Handle<Map> GetMonomorphicReceiverType() {
    269     UNREACHABLE();
    270     return Handle<Map>();
    271   }
    272 
    273   ExternalArrayType external_array_type() const {
    274     return external_array_type_;
    275   }
    276   void set_external_array_type(ExternalArrayType array_type) {
    277     external_array_type_ = array_type;
    278   }
    279 
    280  private:
    281   ExternalArrayType external_array_type_;
    282 };
    283 
    284 
    285 /**
    286  * A sentinel used during pre parsing that represents some expression
    287  * that is a valid left hand side without having to actually build
    288  * the expression.
    289  */
    290 class ValidLeftHandSideSentinel: public Expression {
    291  public:
    292   virtual bool IsValidLeftHandSide() { return true; }
    293   virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
    294   virtual bool IsInlineable() const;
    295 };
    296 
    297 
    298 class BreakableStatement: public Statement {
    299  public:
    300   enum Type {
    301     TARGET_FOR_ANONYMOUS,
    302     TARGET_FOR_NAMED_ONLY
    303   };
    304 
    305   // The labels associated with this statement. May be NULL;
    306   // if it is != NULL, guaranteed to contain at least one entry.
    307   ZoneStringList* labels() const { return labels_; }
    308 
    309   // Type testing & conversion.
    310   virtual BreakableStatement* AsBreakableStatement() { return this; }
    311 
    312   // Code generation
    313   Label* break_target() { return &break_target_; }
    314 
    315   // Testers.
    316   bool is_target_for_anonymous() const { return type_ == TARGET_FOR_ANONYMOUS; }
    317 
    318   // Bailout support.
    319   int EntryId() const { return entry_id_; }
    320   int ExitId() const { return exit_id_; }
    321 
    322  protected:
    323   inline BreakableStatement(ZoneStringList* labels, Type type);
    324 
    325  private:
    326   ZoneStringList* labels_;
    327   Type type_;
    328   Label break_target_;
    329   int entry_id_;
    330   int exit_id_;
    331 };
    332 
    333 
    334 class Block: public BreakableStatement {
    335  public:
    336   inline Block(ZoneStringList* labels, int capacity, bool is_initializer_block);
    337 
    338   DECLARE_NODE_TYPE(Block)
    339 
    340   virtual Assignment* StatementAsSimpleAssignment() {
    341     if (statements_.length() != 1) return NULL;
    342     return statements_[0]->StatementAsSimpleAssignment();
    343   }
    344 
    345   virtual CountOperation* StatementAsCountOperation() {
    346     if (statements_.length() != 1) return NULL;
    347     return statements_[0]->StatementAsCountOperation();
    348   }
    349 
    350   virtual bool IsInlineable() const;
    351 
    352   void AddStatement(Statement* statement) { statements_.Add(statement); }
    353 
    354   ZoneList<Statement*>* statements() { return &statements_; }
    355   bool is_initializer_block() const { return is_initializer_block_; }
    356 
    357  private:
    358   ZoneList<Statement*> statements_;
    359   bool is_initializer_block_;
    360 };
    361 
    362 
    363 class Declaration: public AstNode {
    364  public:
    365   Declaration(VariableProxy* proxy, Variable::Mode mode, FunctionLiteral* fun)
    366       : proxy_(proxy),
    367         mode_(mode),
    368         fun_(fun) {
    369     ASSERT(mode == Variable::VAR || mode == Variable::CONST);
    370     // At the moment there are no "const functions"'s in JavaScript...
    371     ASSERT(fun == NULL || mode == Variable::VAR);
    372   }
    373 
    374   DECLARE_NODE_TYPE(Declaration)
    375 
    376   VariableProxy* proxy() const { return proxy_; }
    377   Variable::Mode mode() const { return mode_; }
    378   FunctionLiteral* fun() const { return fun_; }  // may be NULL
    379   virtual bool IsInlineable() const;
    380 
    381  private:
    382   VariableProxy* proxy_;
    383   Variable::Mode mode_;
    384   FunctionLiteral* fun_;
    385 };
    386 
    387 
    388 class IterationStatement: public BreakableStatement {
    389  public:
    390   // Type testing & conversion.
    391   virtual IterationStatement* AsIterationStatement() { return this; }
    392 
    393   Statement* body() const { return body_; }
    394 
    395   // Bailout support.
    396   int OsrEntryId() const { return osr_entry_id_; }
    397   virtual int ContinueId() const = 0;
    398 
    399   // Code generation
    400   Label* continue_target()  { return &continue_target_; }
    401 
    402  protected:
    403   explicit inline IterationStatement(ZoneStringList* labels);
    404 
    405   void Initialize(Statement* body) {
    406     body_ = body;
    407   }
    408 
    409  private:
    410   Statement* body_;
    411   Label continue_target_;
    412   int osr_entry_id_;
    413 };
    414 
    415 
    416 class DoWhileStatement: public IterationStatement {
    417  public:
    418   explicit inline DoWhileStatement(ZoneStringList* labels);
    419 
    420   DECLARE_NODE_TYPE(DoWhileStatement)
    421 
    422   void Initialize(Expression* cond, Statement* body) {
    423     IterationStatement::Initialize(body);
    424     cond_ = cond;
    425   }
    426 
    427   Expression* cond() const { return cond_; }
    428 
    429   // Position where condition expression starts. We need it to make
    430   // the loop's condition a breakable location.
    431   int condition_position() { return condition_position_; }
    432   void set_condition_position(int pos) { condition_position_ = pos; }
    433 
    434   // Bailout support.
    435   virtual int ContinueId() const { return continue_id_; }
    436   int BackEdgeId() const { return back_edge_id_; }
    437 
    438   virtual bool IsInlineable() const;
    439 
    440  private:
    441   Expression* cond_;
    442   int condition_position_;
    443   int continue_id_;
    444   int back_edge_id_;
    445 };
    446 
    447 
    448 class WhileStatement: public IterationStatement {
    449  public:
    450   explicit inline WhileStatement(ZoneStringList* labels);
    451 
    452   DECLARE_NODE_TYPE(WhileStatement)
    453 
    454   void Initialize(Expression* cond, Statement* body) {
    455     IterationStatement::Initialize(body);
    456     cond_ = cond;
    457   }
    458 
    459   Expression* cond() const { return cond_; }
    460   bool may_have_function_literal() const {
    461     return may_have_function_literal_;
    462   }
    463   void set_may_have_function_literal(bool value) {
    464     may_have_function_literal_ = value;
    465   }
    466   virtual bool IsInlineable() const;
    467 
    468   // Bailout support.
    469   virtual int ContinueId() const { return EntryId(); }
    470   int BodyId() const { return body_id_; }
    471 
    472  private:
    473   Expression* cond_;
    474   // True if there is a function literal subexpression in the condition.
    475   bool may_have_function_literal_;
    476   int body_id_;
    477 };
    478 
    479 
    480 class ForStatement: public IterationStatement {
    481  public:
    482   explicit inline ForStatement(ZoneStringList* labels);
    483 
    484   DECLARE_NODE_TYPE(ForStatement)
    485 
    486   void Initialize(Statement* init,
    487                   Expression* cond,
    488                   Statement* next,
    489                   Statement* body) {
    490     IterationStatement::Initialize(body);
    491     init_ = init;
    492     cond_ = cond;
    493     next_ = next;
    494   }
    495 
    496   Statement* init() const { return init_; }
    497   Expression* cond() const { return cond_; }
    498   Statement* next() const { return next_; }
    499 
    500   bool may_have_function_literal() const {
    501     return may_have_function_literal_;
    502   }
    503   void set_may_have_function_literal(bool value) {
    504     may_have_function_literal_ = value;
    505   }
    506 
    507   // Bailout support.
    508   virtual int ContinueId() const { return continue_id_; }
    509   int BodyId() const { return body_id_; }
    510 
    511   bool is_fast_smi_loop() { return loop_variable_ != NULL; }
    512   Variable* loop_variable() { return loop_variable_; }
    513   void set_loop_variable(Variable* var) { loop_variable_ = var; }
    514   virtual bool IsInlineable() const;
    515 
    516  private:
    517   Statement* init_;
    518   Expression* cond_;
    519   Statement* next_;
    520   // True if there is a function literal subexpression in the condition.
    521   bool may_have_function_literal_;
    522   Variable* loop_variable_;
    523   int continue_id_;
    524   int body_id_;
    525 };
    526 
    527 
    528 class ForInStatement: public IterationStatement {
    529  public:
    530   explicit inline ForInStatement(ZoneStringList* labels);
    531 
    532   DECLARE_NODE_TYPE(ForInStatement)
    533 
    534   void Initialize(Expression* each, Expression* enumerable, Statement* body) {
    535     IterationStatement::Initialize(body);
    536     each_ = each;
    537     enumerable_ = enumerable;
    538   }
    539 
    540   Expression* each() const { return each_; }
    541   Expression* enumerable() const { return enumerable_; }
    542   virtual bool IsInlineable() const;
    543 
    544   // Bailout support.
    545   int AssignmentId() const { return assignment_id_; }
    546   virtual int ContinueId() const { return EntryId(); }
    547 
    548  private:
    549   Expression* each_;
    550   Expression* enumerable_;
    551   int assignment_id_;
    552 };
    553 
    554 
    555 class ExpressionStatement: public Statement {
    556  public:
    557   explicit ExpressionStatement(Expression* expression)
    558       : expression_(expression) { }
    559 
    560   DECLARE_NODE_TYPE(ExpressionStatement)
    561 
    562   virtual bool IsInlineable() const;
    563 
    564   virtual Assignment* StatementAsSimpleAssignment();
    565   virtual CountOperation* StatementAsCountOperation();
    566 
    567   void set_expression(Expression* e) { expression_ = e; }
    568   Expression* expression() const { return expression_; }
    569 
    570  private:
    571   Expression* expression_;
    572 };
    573 
    574 
    575 class ContinueStatement: public Statement {
    576  public:
    577   explicit ContinueStatement(IterationStatement* target)
    578       : target_(target) { }
    579 
    580   DECLARE_NODE_TYPE(ContinueStatement)
    581 
    582   IterationStatement* target() const { return target_; }
    583   virtual bool IsInlineable() const;
    584 
    585  private:
    586   IterationStatement* target_;
    587 };
    588 
    589 
    590 class BreakStatement: public Statement {
    591  public:
    592   explicit BreakStatement(BreakableStatement* target)
    593       : target_(target) { }
    594 
    595   DECLARE_NODE_TYPE(BreakStatement)
    596 
    597   BreakableStatement* target() const { return target_; }
    598   virtual bool IsInlineable() const;
    599 
    600  private:
    601   BreakableStatement* target_;
    602 };
    603 
    604 
    605 class ReturnStatement: public Statement {
    606  public:
    607   explicit ReturnStatement(Expression* expression)
    608       : expression_(expression) { }
    609 
    610   DECLARE_NODE_TYPE(ReturnStatement)
    611 
    612   Expression* expression() const { return expression_; }
    613   virtual bool IsInlineable() const;
    614 
    615  private:
    616   Expression* expression_;
    617 };
    618 
    619 
    620 class WithEnterStatement: public Statement {
    621  public:
    622   explicit WithEnterStatement(Expression* expression, bool is_catch_block)
    623       : expression_(expression), is_catch_block_(is_catch_block) { }
    624 
    625   DECLARE_NODE_TYPE(WithEnterStatement)
    626 
    627   Expression* expression() const { return expression_; }
    628 
    629   bool is_catch_block() const { return is_catch_block_; }
    630   virtual bool IsInlineable() const;
    631 
    632  private:
    633   Expression* expression_;
    634   bool is_catch_block_;
    635 };
    636 
    637 
    638 class WithExitStatement: public Statement {
    639  public:
    640   WithExitStatement() { }
    641 
    642   virtual bool IsInlineable() const;
    643 
    644   DECLARE_NODE_TYPE(WithExitStatement)
    645 };
    646 
    647 
    648 class CaseClause: public ZoneObject {
    649  public:
    650   CaseClause(Expression* label, ZoneList<Statement*>* statements, int pos);
    651 
    652   bool is_default() const { return label_ == NULL; }
    653   Expression* label() const {
    654     CHECK(!is_default());
    655     return label_;
    656   }
    657   Label* body_target() { return &body_target_; }
    658   ZoneList<Statement*>* statements() const { return statements_; }
    659 
    660   int position() const { return position_; }
    661   void set_position(int pos) { position_ = pos; }
    662 
    663   int EntryId() { return entry_id_; }
    664 
    665   // Type feedback information.
    666   void RecordTypeFeedback(TypeFeedbackOracle* oracle);
    667   bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
    668   bool IsObjectCompare() { return compare_type_ == OBJECT_ONLY; }
    669 
    670  private:
    671   Expression* label_;
    672   Label body_target_;
    673   ZoneList<Statement*>* statements_;
    674   int position_;
    675   enum CompareTypeFeedback { NONE, SMI_ONLY, OBJECT_ONLY };
    676   CompareTypeFeedback compare_type_;
    677   int entry_id_;
    678 };
    679 
    680 
    681 class SwitchStatement: public BreakableStatement {
    682  public:
    683   explicit inline SwitchStatement(ZoneStringList* labels);
    684 
    685   DECLARE_NODE_TYPE(SwitchStatement)
    686 
    687   void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) {
    688     tag_ = tag;
    689     cases_ = cases;
    690   }
    691 
    692   Expression* tag() const { return tag_; }
    693   ZoneList<CaseClause*>* cases() const { return cases_; }
    694   virtual bool IsInlineable() const;
    695 
    696  private:
    697   Expression* tag_;
    698   ZoneList<CaseClause*>* cases_;
    699 };
    700 
    701 
    702 // If-statements always have non-null references to their then- and
    703 // else-parts. When parsing if-statements with no explicit else-part,
    704 // the parser implicitly creates an empty statement. Use the
    705 // HasThenStatement() and HasElseStatement() functions to check if a
    706 // given if-statement has a then- or an else-part containing code.
    707 class IfStatement: public Statement {
    708  public:
    709   IfStatement(Expression* condition,
    710               Statement* then_statement,
    711               Statement* else_statement)
    712       : condition_(condition),
    713         then_statement_(then_statement),
    714         else_statement_(else_statement),
    715         then_id_(GetNextId()),
    716         else_id_(GetNextId()) {
    717   }
    718 
    719   DECLARE_NODE_TYPE(IfStatement)
    720 
    721   virtual bool IsInlineable() const;
    722 
    723   bool HasThenStatement() const { return !then_statement()->IsEmpty(); }
    724   bool HasElseStatement() const { return !else_statement()->IsEmpty(); }
    725 
    726   Expression* condition() const { return condition_; }
    727   Statement* then_statement() const { return then_statement_; }
    728   Statement* else_statement() const { return else_statement_; }
    729 
    730   int ThenId() const { return then_id_; }
    731   int ElseId() const { return else_id_; }
    732 
    733  private:
    734   Expression* condition_;
    735   Statement* then_statement_;
    736   Statement* else_statement_;
    737   int then_id_;
    738   int else_id_;
    739 };
    740 
    741 
    742 // NOTE: TargetCollectors are represented as nodes to fit in the target
    743 // stack in the compiler; this should probably be reworked.
    744 class TargetCollector: public AstNode {
    745  public:
    746   explicit TargetCollector(ZoneList<Label*>* targets)
    747       : targets_(targets) {
    748   }
    749 
    750   // Adds a jump target to the collector. The collector stores a pointer not
    751   // a copy of the target to make binding work, so make sure not to pass in
    752   // references to something on the stack.
    753   void AddTarget(Label* target);
    754 
    755   // Virtual behaviour. TargetCollectors are never part of the AST.
    756   virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
    757   virtual TargetCollector* AsTargetCollector() { return this; }
    758 
    759   ZoneList<Label*>* targets() { return targets_; }
    760   virtual bool IsInlineable() const;
    761 
    762  private:
    763   ZoneList<Label*>* targets_;
    764 };
    765 
    766 
    767 class TryStatement: public Statement {
    768  public:
    769   explicit TryStatement(Block* try_block)
    770       : try_block_(try_block), escaping_targets_(NULL) { }
    771 
    772   void set_escaping_targets(ZoneList<Label*>* targets) {
    773     escaping_targets_ = targets;
    774   }
    775 
    776   Block* try_block() const { return try_block_; }
    777   ZoneList<Label*>* escaping_targets() const { return escaping_targets_; }
    778   virtual bool IsInlineable() const;
    779 
    780  private:
    781   Block* try_block_;
    782   ZoneList<Label*>* escaping_targets_;
    783 };
    784 
    785 
    786 class TryCatchStatement: public TryStatement {
    787  public:
    788   TryCatchStatement(Block* try_block,
    789                     VariableProxy* catch_var,
    790                     Block* catch_block)
    791       : TryStatement(try_block),
    792         catch_var_(catch_var),
    793         catch_block_(catch_block) {
    794   }
    795 
    796   DECLARE_NODE_TYPE(TryCatchStatement)
    797 
    798   VariableProxy* catch_var() const { return catch_var_; }
    799   Block* catch_block() const { return catch_block_; }
    800   virtual bool IsInlineable() const;
    801 
    802  private:
    803   VariableProxy* catch_var_;
    804   Block* catch_block_;
    805 };
    806 
    807 
    808 class TryFinallyStatement: public TryStatement {
    809  public:
    810   TryFinallyStatement(Block* try_block, Block* finally_block)
    811       : TryStatement(try_block),
    812         finally_block_(finally_block) { }
    813 
    814   DECLARE_NODE_TYPE(TryFinallyStatement)
    815 
    816   Block* finally_block() const { return finally_block_; }
    817   virtual bool IsInlineable() const;
    818 
    819  private:
    820   Block* finally_block_;
    821 };
    822 
    823 
    824 class DebuggerStatement: public Statement {
    825  public:
    826   DECLARE_NODE_TYPE(DebuggerStatement)
    827   virtual bool IsInlineable() const;
    828 };
    829 
    830 
    831 class EmptyStatement: public Statement {
    832  public:
    833   DECLARE_NODE_TYPE(EmptyStatement)
    834 
    835   virtual bool IsInlineable() const;
    836 };
    837 
    838 
    839 class Literal: public Expression {
    840  public:
    841   explicit Literal(Handle<Object> handle) : handle_(handle) { }
    842 
    843   DECLARE_NODE_TYPE(Literal)
    844 
    845   virtual bool IsTrivial() { return true; }
    846   virtual bool IsSmiLiteral() { return handle_->IsSmi(); }
    847 
    848   // Check if this literal is identical to the other literal.
    849   bool IsIdenticalTo(const Literal* other) const {
    850     return handle_.is_identical_to(other->handle_);
    851   }
    852 
    853   virtual bool IsPropertyName() {
    854     if (handle_->IsSymbol()) {
    855       uint32_t ignored;
    856       return !String::cast(*handle_)->AsArrayIndex(&ignored);
    857     }
    858     return false;
    859   }
    860 
    861   Handle<String> AsPropertyName() {
    862     ASSERT(IsPropertyName());
    863     return Handle<String>::cast(handle_);
    864   }
    865 
    866   virtual bool ToBooleanIsTrue() { return handle_->ToBoolean()->IsTrue(); }
    867   virtual bool ToBooleanIsFalse() { return handle_->ToBoolean()->IsFalse(); }
    868 
    869   // Identity testers.
    870   bool IsNull() const {
    871     ASSERT(!handle_.is_null());
    872     return handle_->IsNull();
    873   }
    874   bool IsTrue() const {
    875     ASSERT(!handle_.is_null());
    876     return handle_->IsTrue();
    877   }
    878   bool IsFalse() const {
    879     ASSERT(!handle_.is_null());
    880     return handle_->IsFalse();
    881   }
    882 
    883   Handle<Object> handle() const { return handle_; }
    884   virtual bool IsInlineable() const;
    885 
    886  private:
    887   Handle<Object> handle_;
    888 };
    889 
    890 
    891 // Base class for literals that needs space in the corresponding JSFunction.
    892 class MaterializedLiteral: public Expression {
    893  public:
    894   explicit MaterializedLiteral(int literal_index, bool is_simple, int depth)
    895       : literal_index_(literal_index), is_simple_(is_simple), depth_(depth) {}
    896 
    897   virtual MaterializedLiteral* AsMaterializedLiteral() { return this; }
    898 
    899   int literal_index() { return literal_index_; }
    900 
    901   // A materialized literal is simple if the values consist of only
    902   // constants and simple object and array literals.
    903   bool is_simple() const { return is_simple_; }
    904 
    905   int depth() const { return depth_; }
    906   virtual bool IsInlineable() const;
    907 
    908  private:
    909   int literal_index_;
    910   bool is_simple_;
    911   int depth_;
    912 };
    913 
    914 
    915 // An object literal has a boilerplate object that is used
    916 // for minimizing the work when constructing it at runtime.
    917 class ObjectLiteral: public MaterializedLiteral {
    918  public:
    919   // Property is used for passing information
    920   // about an object literal's properties from the parser
    921   // to the code generator.
    922   class Property: public ZoneObject {
    923    public:
    924     enum Kind {
    925       CONSTANT,              // Property with constant value (compile time).
    926       COMPUTED,              // Property with computed value (execution time).
    927       MATERIALIZED_LITERAL,  // Property value is a materialized literal.
    928       GETTER, SETTER,        // Property is an accessor function.
    929       PROTOTYPE              // Property is __proto__.
    930     };
    931 
    932     Property(Literal* key, Expression* value);
    933     Property(bool is_getter, FunctionLiteral* value);
    934 
    935     Literal* key() { return key_; }
    936     Expression* value() { return value_; }
    937     Kind kind() { return kind_; }
    938 
    939     bool IsCompileTimeValue();
    940 
    941     void set_emit_store(bool emit_store);
    942     bool emit_store();
    943 
    944    private:
    945     Literal* key_;
    946     Expression* value_;
    947     Kind kind_;
    948     bool emit_store_;
    949   };
    950 
    951   ObjectLiteral(Handle<FixedArray> constant_properties,
    952                 ZoneList<Property*>* properties,
    953                 int literal_index,
    954                 bool is_simple,
    955                 bool fast_elements,
    956                 int depth,
    957                 bool has_function)
    958       : MaterializedLiteral(literal_index, is_simple, depth),
    959         constant_properties_(constant_properties),
    960         properties_(properties),
    961         fast_elements_(fast_elements),
    962         has_function_(has_function) {}
    963 
    964   DECLARE_NODE_TYPE(ObjectLiteral)
    965 
    966   Handle<FixedArray> constant_properties() const {
    967     return constant_properties_;
    968   }
    969   ZoneList<Property*>* properties() const { return properties_; }
    970 
    971   bool fast_elements() const { return fast_elements_; }
    972 
    973   bool has_function() { return has_function_; }
    974 
    975   // Mark all computed expressions that are bound to a key that
    976   // is shadowed by a later occurrence of the same key. For the
    977   // marked expressions, no store code is emitted.
    978   void CalculateEmitStore();
    979 
    980   enum Flags {
    981     kNoFlags = 0,
    982     kFastElements = 1,
    983     kHasFunction = 1 << 1
    984   };
    985 
    986  private:
    987   Handle<FixedArray> constant_properties_;
    988   ZoneList<Property*>* properties_;
    989   bool fast_elements_;
    990   bool has_function_;
    991 };
    992 
    993 
    994 // Node for capturing a regexp literal.
    995 class RegExpLiteral: public MaterializedLiteral {
    996  public:
    997   RegExpLiteral(Handle<String> pattern,
    998                 Handle<String> flags,
    999                 int literal_index)
   1000       : MaterializedLiteral(literal_index, false, 1),
   1001         pattern_(pattern),
   1002         flags_(flags) {}
   1003 
   1004   DECLARE_NODE_TYPE(RegExpLiteral)
   1005 
   1006   Handle<String> pattern() const { return pattern_; }
   1007   Handle<String> flags() const { return flags_; }
   1008 
   1009  private:
   1010   Handle<String> pattern_;
   1011   Handle<String> flags_;
   1012 };
   1013 
   1014 // An array literal has a literals object that is used
   1015 // for minimizing the work when constructing it at runtime.
   1016 class ArrayLiteral: public MaterializedLiteral {
   1017  public:
   1018   ArrayLiteral(Handle<FixedArray> constant_elements,
   1019                ZoneList<Expression*>* values,
   1020                int literal_index,
   1021                bool is_simple,
   1022                int depth)
   1023       : MaterializedLiteral(literal_index, is_simple, depth),
   1024         constant_elements_(constant_elements),
   1025         values_(values),
   1026         first_element_id_(ReserveIdRange(values->length())) {}
   1027 
   1028   DECLARE_NODE_TYPE(ArrayLiteral)
   1029 
   1030   Handle<FixedArray> constant_elements() const { return constant_elements_; }
   1031   ZoneList<Expression*>* values() const { return values_; }
   1032 
   1033   // Return an AST id for an element that is used in simulate instructions.
   1034   int GetIdForElement(int i) { return first_element_id_ + i; }
   1035 
   1036  private:
   1037   Handle<FixedArray> constant_elements_;
   1038   ZoneList<Expression*>* values_;
   1039   int first_element_id_;
   1040 };
   1041 
   1042 
   1043 // Node for constructing a context extension object for a catch block.
   1044 // The catch context extension object has one property, the catch
   1045 // variable, which should be DontDelete.
   1046 class CatchExtensionObject: public Expression {
   1047  public:
   1048   CatchExtensionObject(Literal* key, VariableProxy* value)
   1049       : key_(key), value_(value) {
   1050   }
   1051 
   1052   DECLARE_NODE_TYPE(CatchExtensionObject)
   1053 
   1054   Literal* key() const { return key_; }
   1055   VariableProxy* value() const { return value_; }
   1056   virtual bool IsInlineable() const;
   1057 
   1058  private:
   1059   Literal* key_;
   1060   VariableProxy* value_;
   1061 };
   1062 
   1063 
   1064 class VariableProxy: public Expression {
   1065  public:
   1066   explicit VariableProxy(Variable* var);
   1067 
   1068   DECLARE_NODE_TYPE(VariableProxy)
   1069 
   1070   // Type testing & conversion
   1071   virtual Property* AsProperty() {
   1072     return var_ == NULL ? NULL : var_->AsProperty();
   1073   }
   1074 
   1075   Variable* AsVariable() {
   1076     if (this == NULL || var_ == NULL) return NULL;
   1077     Expression* rewrite = var_->rewrite();
   1078     if (rewrite == NULL || rewrite->AsSlot() != NULL) return var_;
   1079     return NULL;
   1080   }
   1081 
   1082   virtual bool IsValidLeftHandSide() {
   1083     return var_ == NULL ? true : var_->IsValidLeftHandSide();
   1084   }
   1085 
   1086   virtual bool IsTrivial() {
   1087     // Reading from a mutable variable is a side effect, but the
   1088     // variable for 'this' is immutable.
   1089     return is_this_ || is_trivial_;
   1090   }
   1091 
   1092   virtual bool IsInlineable() const;
   1093 
   1094   bool IsVariable(Handle<String> n) {
   1095     return !is_this() && name().is_identical_to(n);
   1096   }
   1097 
   1098   bool IsArguments() {
   1099     Variable* variable = AsVariable();
   1100     return (variable == NULL) ? false : variable->is_arguments();
   1101   }
   1102 
   1103   Handle<String> name() const { return name_; }
   1104   Variable* var() const { return var_; }
   1105   bool is_this() const { return is_this_; }
   1106   bool inside_with() const { return inside_with_; }
   1107   int position() const { return position_; }
   1108 
   1109   void MarkAsTrivial() { is_trivial_ = true; }
   1110 
   1111   // Bind this proxy to the variable var.
   1112   void BindTo(Variable* var);
   1113 
   1114  protected:
   1115   Handle<String> name_;
   1116   Variable* var_;  // resolved variable, or NULL
   1117   bool is_this_;
   1118   bool inside_with_;
   1119   bool is_trivial_;
   1120   int position_;
   1121 
   1122   VariableProxy(Handle<String> name,
   1123                 bool is_this,
   1124                 bool inside_with,
   1125                 int position = RelocInfo::kNoPosition);
   1126   explicit VariableProxy(bool is_this);
   1127 
   1128   friend class Scope;
   1129 };
   1130 
   1131 
   1132 class VariableProxySentinel: public VariableProxy {
   1133  public:
   1134   virtual bool IsValidLeftHandSide() { return !is_this(); }
   1135 
   1136  private:
   1137   explicit VariableProxySentinel(bool is_this) : VariableProxy(is_this) { }
   1138 
   1139   friend class AstSentinels;
   1140 };
   1141 
   1142 
   1143 class Slot: public Expression {
   1144  public:
   1145   enum Type {
   1146     // A slot in the parameter section on the stack. index() is
   1147     // the parameter index, counting left-to-right, starting at 0.
   1148     PARAMETER,
   1149 
   1150     // A slot in the local section on the stack. index() is
   1151     // the variable index in the stack frame, starting at 0.
   1152     LOCAL,
   1153 
   1154     // An indexed slot in a heap context. index() is the
   1155     // variable index in the context object on the heap,
   1156     // starting at 0. var()->scope() is the corresponding
   1157     // scope.
   1158     CONTEXT,
   1159 
   1160     // A named slot in a heap context. var()->name() is the
   1161     // variable name in the context object on the heap,
   1162     // with lookup starting at the current context. index()
   1163     // is invalid.
   1164     LOOKUP
   1165   };
   1166 
   1167   Slot(Variable* var, Type type, int index)
   1168       : var_(var), type_(type), index_(index) {
   1169     ASSERT(var != NULL);
   1170   }
   1171 
   1172   virtual void Accept(AstVisitor* v);
   1173 
   1174   virtual Slot* AsSlot() { return this; }
   1175 
   1176   bool IsStackAllocated() { return type_ == PARAMETER || type_ == LOCAL; }
   1177 
   1178   // Accessors
   1179   Variable* var() const { return var_; }
   1180   Type type() const { return type_; }
   1181   int index() const { return index_; }
   1182   bool is_arguments() const { return var_->is_arguments(); }
   1183   virtual bool IsInlineable() const;
   1184 
   1185  private:
   1186   Variable* var_;
   1187   Type type_;
   1188   int index_;
   1189 };
   1190 
   1191 
   1192 class Property: public Expression {
   1193  public:
   1194   // Synthetic properties are property lookups introduced by the system,
   1195   // to objects that aren't visible to the user. Function calls to synthetic
   1196   // properties should use the global object as receiver, not the base object
   1197   // of the resolved Reference.
   1198   enum Type { NORMAL, SYNTHETIC };
   1199   Property(Expression* obj, Expression* key, int pos, Type type = NORMAL)
   1200       : obj_(obj),
   1201         key_(key),
   1202         pos_(pos),
   1203         type_(type),
   1204         receiver_types_(NULL),
   1205         is_monomorphic_(false),
   1206         is_array_length_(false),
   1207         is_string_length_(false),
   1208         is_string_access_(false),
   1209         is_function_prototype_(false),
   1210         is_arguments_access_(false) { }
   1211 
   1212   DECLARE_NODE_TYPE(Property)
   1213 
   1214   virtual bool IsValidLeftHandSide() { return true; }
   1215   virtual bool IsInlineable() const;
   1216 
   1217   Expression* obj() const { return obj_; }
   1218   Expression* key() const { return key_; }
   1219   virtual int position() const { return pos_; }
   1220   bool is_synthetic() const { return type_ == SYNTHETIC; }
   1221 
   1222   bool IsStringLength() const { return is_string_length_; }
   1223   bool IsStringAccess() const { return is_string_access_; }
   1224   bool IsFunctionPrototype() const { return is_function_prototype_; }
   1225 
   1226   // Marks that this is actually an argument rewritten to a keyed property
   1227   // accessing the argument through the arguments shadow object.
   1228   void set_is_arguments_access(bool is_arguments_access) {
   1229     is_arguments_access_ = is_arguments_access;
   1230   }
   1231   bool is_arguments_access() const { return is_arguments_access_; }
   1232 
   1233   // Type feedback information.
   1234   void RecordTypeFeedback(TypeFeedbackOracle* oracle);
   1235   virtual bool IsMonomorphic() { return is_monomorphic_; }
   1236   virtual ZoneMapList* GetReceiverTypes() { return receiver_types_; }
   1237   virtual bool IsArrayLength() { return is_array_length_; }
   1238   virtual Handle<Map> GetMonomorphicReceiverType() {
   1239     return monomorphic_receiver_type_;
   1240   }
   1241 
   1242  private:
   1243   Expression* obj_;
   1244   Expression* key_;
   1245   int pos_;
   1246   Type type_;
   1247 
   1248   ZoneMapList* receiver_types_;
   1249   bool is_monomorphic_ : 1;
   1250   bool is_array_length_ : 1;
   1251   bool is_string_length_ : 1;
   1252   bool is_string_access_ : 1;
   1253   bool is_function_prototype_ : 1;
   1254   bool is_arguments_access_ : 1;
   1255   Handle<Map> monomorphic_receiver_type_;
   1256 };
   1257 
   1258 
   1259 class Call: public Expression {
   1260  public:
   1261   Call(Expression* expression, ZoneList<Expression*>* arguments, int pos)
   1262       : expression_(expression),
   1263         arguments_(arguments),
   1264         pos_(pos),
   1265         is_monomorphic_(false),
   1266         check_type_(RECEIVER_MAP_CHECK),
   1267         receiver_types_(NULL),
   1268         return_id_(GetNextId()) {
   1269   }
   1270 
   1271   DECLARE_NODE_TYPE(Call)
   1272 
   1273   virtual bool IsInlineable() const;
   1274 
   1275   Expression* expression() const { return expression_; }
   1276   ZoneList<Expression*>* arguments() const { return arguments_; }
   1277   virtual int position() const { return pos_; }
   1278 
   1279   void RecordTypeFeedback(TypeFeedbackOracle* oracle);
   1280   virtual ZoneMapList* GetReceiverTypes() { return receiver_types_; }
   1281   virtual bool IsMonomorphic() { return is_monomorphic_; }
   1282   CheckType check_type() const { return check_type_; }
   1283   Handle<JSFunction> target() { return target_; }
   1284   Handle<JSObject> holder() { return holder_; }
   1285   Handle<JSGlobalPropertyCell> cell() { return cell_; }
   1286 
   1287   bool ComputeTarget(Handle<Map> type, Handle<String> name);
   1288   bool ComputeGlobalTarget(Handle<GlobalObject> global, LookupResult* lookup);
   1289 
   1290   // Bailout support.
   1291   int ReturnId() const { return return_id_; }
   1292 
   1293 #ifdef DEBUG
   1294   // Used to assert that the FullCodeGenerator records the return site.
   1295   bool return_is_recorded_;
   1296 #endif
   1297 
   1298  private:
   1299   Expression* expression_;
   1300   ZoneList<Expression*>* arguments_;
   1301   int pos_;
   1302 
   1303   bool is_monomorphic_;
   1304   CheckType check_type_;
   1305   ZoneMapList* receiver_types_;
   1306   Handle<JSFunction> target_;
   1307   Handle<JSObject> holder_;
   1308   Handle<JSGlobalPropertyCell> cell_;
   1309 
   1310   int return_id_;
   1311 };
   1312 
   1313 
   1314 class AstSentinels {
   1315  public:
   1316   ~AstSentinels() { }
   1317 
   1318   // Returns a property singleton property access on 'this'.  Used
   1319   // during preparsing.
   1320   Property* this_property() { return &this_property_; }
   1321   VariableProxySentinel* this_proxy() { return &this_proxy_; }
   1322   VariableProxySentinel* identifier_proxy() { return &identifier_proxy_; }
   1323   ValidLeftHandSideSentinel* valid_left_hand_side_sentinel() {
   1324     return &valid_left_hand_side_sentinel_;
   1325   }
   1326   Call* call_sentinel() { return &call_sentinel_; }
   1327   EmptyStatement* empty_statement() { return &empty_statement_; }
   1328 
   1329  private:
   1330   AstSentinels();
   1331   VariableProxySentinel this_proxy_;
   1332   VariableProxySentinel identifier_proxy_;
   1333   ValidLeftHandSideSentinel valid_left_hand_side_sentinel_;
   1334   Property this_property_;
   1335   Call call_sentinel_;
   1336   EmptyStatement empty_statement_;
   1337 
   1338   friend class Isolate;
   1339 
   1340   DISALLOW_COPY_AND_ASSIGN(AstSentinels);
   1341 };
   1342 
   1343 
   1344 class CallNew: public Expression {
   1345  public:
   1346   CallNew(Expression* expression, ZoneList<Expression*>* arguments, int pos)
   1347       : expression_(expression), arguments_(arguments), pos_(pos) { }
   1348 
   1349   DECLARE_NODE_TYPE(CallNew)
   1350 
   1351   virtual bool IsInlineable() const;
   1352 
   1353   Expression* expression() const { return expression_; }
   1354   ZoneList<Expression*>* arguments() const { return arguments_; }
   1355   virtual int position() const { return pos_; }
   1356 
   1357  private:
   1358   Expression* expression_;
   1359   ZoneList<Expression*>* arguments_;
   1360   int pos_;
   1361 };
   1362 
   1363 
   1364 // The CallRuntime class does not represent any official JavaScript
   1365 // language construct. Instead it is used to call a C or JS function
   1366 // with a set of arguments. This is used from the builtins that are
   1367 // implemented in JavaScript (see "v8natives.js").
   1368 class CallRuntime: public Expression {
   1369  public:
   1370   CallRuntime(Handle<String> name,
   1371               const Runtime::Function* function,
   1372               ZoneList<Expression*>* arguments)
   1373       : name_(name), function_(function), arguments_(arguments) { }
   1374 
   1375   DECLARE_NODE_TYPE(CallRuntime)
   1376 
   1377   virtual bool IsInlineable() const;
   1378 
   1379   Handle<String> name() const { return name_; }
   1380   const Runtime::Function* function() const { return function_; }
   1381   ZoneList<Expression*>* arguments() const { return arguments_; }
   1382   bool is_jsruntime() const { return function_ == NULL; }
   1383 
   1384  private:
   1385   Handle<String> name_;
   1386   const Runtime::Function* function_;
   1387   ZoneList<Expression*>* arguments_;
   1388 };
   1389 
   1390 
   1391 class UnaryOperation: public Expression {
   1392  public:
   1393   UnaryOperation(Token::Value op, Expression* expression)
   1394       : op_(op), expression_(expression) {
   1395     ASSERT(Token::IsUnaryOp(op));
   1396   }
   1397 
   1398   DECLARE_NODE_TYPE(UnaryOperation)
   1399 
   1400   virtual bool IsInlineable() const;
   1401 
   1402   virtual bool ResultOverwriteAllowed();
   1403 
   1404   Token::Value op() const { return op_; }
   1405   Expression* expression() const { return expression_; }
   1406 
   1407  private:
   1408   Token::Value op_;
   1409   Expression* expression_;
   1410 };
   1411 
   1412 
   1413 class BinaryOperation: public Expression {
   1414  public:
   1415   BinaryOperation(Token::Value op,
   1416                   Expression* left,
   1417                   Expression* right,
   1418                   int pos)
   1419       : op_(op), left_(left), right_(right), pos_(pos) {
   1420     ASSERT(Token::IsBinaryOp(op));
   1421     right_id_ = (op == Token::AND || op == Token::OR)
   1422         ? static_cast<int>(GetNextId())
   1423         : AstNode::kNoNumber;
   1424   }
   1425 
   1426   // Create the binary operation corresponding to a compound assignment.
   1427   explicit BinaryOperation(Assignment* assignment);
   1428 
   1429   DECLARE_NODE_TYPE(BinaryOperation)
   1430 
   1431   virtual bool IsInlineable() const;
   1432 
   1433   virtual bool ResultOverwriteAllowed();
   1434 
   1435   Token::Value op() const { return op_; }
   1436   Expression* left() const { return left_; }
   1437   Expression* right() const { return right_; }
   1438   virtual int position() const { return pos_; }
   1439 
   1440   // Bailout support.
   1441   int RightId() const { return right_id_; }
   1442 
   1443  private:
   1444   Token::Value op_;
   1445   Expression* left_;
   1446   Expression* right_;
   1447   int pos_;
   1448   // The short-circuit logical operations have an AST ID for their
   1449   // right-hand subexpression.
   1450   int right_id_;
   1451 };
   1452 
   1453 
   1454 class CountOperation: public Expression {
   1455  public:
   1456   CountOperation(Token::Value op, bool is_prefix, Expression* expr, int pos)
   1457       : op_(op),
   1458         is_prefix_(is_prefix),
   1459         expression_(expr),
   1460         pos_(pos),
   1461         assignment_id_(GetNextId()),
   1462         count_id_(GetNextId()) { }
   1463 
   1464   DECLARE_NODE_TYPE(CountOperation)
   1465 
   1466   bool is_prefix() const { return is_prefix_; }
   1467   bool is_postfix() const { return !is_prefix_; }
   1468 
   1469   Token::Value op() const { return op_; }
   1470   Token::Value binary_op() {
   1471     return (op() == Token::INC) ? Token::ADD : Token::SUB;
   1472   }
   1473 
   1474   Expression* expression() const { return expression_; }
   1475   virtual int position() const { return pos_; }
   1476 
   1477   virtual void MarkAsStatement() { is_prefix_ = true; }
   1478 
   1479   virtual bool IsInlineable() const;
   1480 
   1481   void RecordTypeFeedback(TypeFeedbackOracle* oracle);
   1482   virtual bool IsMonomorphic() { return is_monomorphic_; }
   1483   virtual Handle<Map> GetMonomorphicReceiverType() {
   1484     return monomorphic_receiver_type_;
   1485   }
   1486 
   1487   // Bailout support.
   1488   int AssignmentId() const { return assignment_id_; }
   1489   int CountId() const { return count_id_; }
   1490 
   1491  private:
   1492   Token::Value op_;
   1493   bool is_prefix_;
   1494   bool is_monomorphic_;
   1495   Expression* expression_;
   1496   int pos_;
   1497   int assignment_id_;
   1498   int count_id_;
   1499   Handle<Map> monomorphic_receiver_type_;
   1500 };
   1501 
   1502 
   1503 class CompareOperation: public Expression {
   1504  public:
   1505   CompareOperation(Token::Value op,
   1506                    Expression* left,
   1507                    Expression* right,
   1508                    int pos)
   1509       : op_(op), left_(left), right_(right), pos_(pos), compare_type_(NONE) {
   1510     ASSERT(Token::IsCompareOp(op));
   1511   }
   1512 
   1513   DECLARE_NODE_TYPE(CompareOperation)
   1514 
   1515   Token::Value op() const { return op_; }
   1516   Expression* left() const { return left_; }
   1517   Expression* right() const { return right_; }
   1518   virtual int position() const { return pos_; }
   1519 
   1520   virtual bool IsInlineable() const;
   1521 
   1522   // Type feedback information.
   1523   void RecordTypeFeedback(TypeFeedbackOracle* oracle);
   1524   bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
   1525   bool IsObjectCompare() { return compare_type_ == OBJECT_ONLY; }
   1526 
   1527  private:
   1528   Token::Value op_;
   1529   Expression* left_;
   1530   Expression* right_;
   1531   int pos_;
   1532 
   1533   enum CompareTypeFeedback { NONE, SMI_ONLY, OBJECT_ONLY };
   1534   CompareTypeFeedback compare_type_;
   1535 };
   1536 
   1537 
   1538 class CompareToNull: public Expression {
   1539  public:
   1540   CompareToNull(bool is_strict, Expression* expression)
   1541       : is_strict_(is_strict), expression_(expression) { }
   1542 
   1543   DECLARE_NODE_TYPE(CompareToNull)
   1544 
   1545   virtual bool IsInlineable() const;
   1546 
   1547   bool is_strict() const { return is_strict_; }
   1548   Token::Value op() const { return is_strict_ ? Token::EQ_STRICT : Token::EQ; }
   1549   Expression* expression() const { return expression_; }
   1550 
   1551  private:
   1552   bool is_strict_;
   1553   Expression* expression_;
   1554 };
   1555 
   1556 
   1557 class Conditional: public Expression {
   1558  public:
   1559   Conditional(Expression* condition,
   1560               Expression* then_expression,
   1561               Expression* else_expression,
   1562               int then_expression_position,
   1563               int else_expression_position)
   1564       : condition_(condition),
   1565         then_expression_(then_expression),
   1566         else_expression_(else_expression),
   1567         then_expression_position_(then_expression_position),
   1568         else_expression_position_(else_expression_position),
   1569         then_id_(GetNextId()),
   1570         else_id_(GetNextId()) {
   1571   }
   1572 
   1573   DECLARE_NODE_TYPE(Conditional)
   1574 
   1575   virtual bool IsInlineable() const;
   1576 
   1577   Expression* condition() const { return condition_; }
   1578   Expression* then_expression() const { return then_expression_; }
   1579   Expression* else_expression() const { return else_expression_; }
   1580 
   1581   int then_expression_position() const { return then_expression_position_; }
   1582   int else_expression_position() const { return else_expression_position_; }
   1583 
   1584   int ThenId() const { return then_id_; }
   1585   int ElseId() const { return else_id_; }
   1586 
   1587  private:
   1588   Expression* condition_;
   1589   Expression* then_expression_;
   1590   Expression* else_expression_;
   1591   int then_expression_position_;
   1592   int else_expression_position_;
   1593   int then_id_;
   1594   int else_id_;
   1595 };
   1596 
   1597 
   1598 class Assignment: public Expression {
   1599  public:
   1600   Assignment(Token::Value op, Expression* target, Expression* value, int pos);
   1601 
   1602   DECLARE_NODE_TYPE(Assignment)
   1603 
   1604   virtual bool IsInlineable() const;
   1605 
   1606   Assignment* AsSimpleAssignment() { return !is_compound() ? this : NULL; }
   1607 
   1608   Token::Value binary_op() const;
   1609 
   1610   Token::Value op() const { return op_; }
   1611   Expression* target() const { return target_; }
   1612   Expression* value() const { return value_; }
   1613   virtual int position() const { return pos_; }
   1614   BinaryOperation* binary_operation() const { return binary_operation_; }
   1615 
   1616   // This check relies on the definition order of token in token.h.
   1617   bool is_compound() const { return op() > Token::ASSIGN; }
   1618 
   1619   // An initialization block is a series of statments of the form
   1620   // x.y.z.a = ...; x.y.z.b = ...; etc. The parser marks the beginning and
   1621   // ending of these blocks to allow for optimizations of initialization
   1622   // blocks.
   1623   bool starts_initialization_block() { return block_start_; }
   1624   bool ends_initialization_block() { return block_end_; }
   1625   void mark_block_start() { block_start_ = true; }
   1626   void mark_block_end() { block_end_ = true; }
   1627 
   1628   // Type feedback information.
   1629   void RecordTypeFeedback(TypeFeedbackOracle* oracle);
   1630   virtual bool IsMonomorphic() { return is_monomorphic_; }
   1631   virtual ZoneMapList* GetReceiverTypes() { return receiver_types_; }
   1632   virtual Handle<Map> GetMonomorphicReceiverType() {
   1633     return monomorphic_receiver_type_;
   1634   }
   1635 
   1636   // Bailout support.
   1637   int CompoundLoadId() const { return compound_load_id_; }
   1638   int AssignmentId() const { return assignment_id_; }
   1639 
   1640  private:
   1641   Token::Value op_;
   1642   Expression* target_;
   1643   Expression* value_;
   1644   int pos_;
   1645   BinaryOperation* binary_operation_;
   1646   int compound_load_id_;
   1647   int assignment_id_;
   1648 
   1649   bool block_start_;
   1650   bool block_end_;
   1651 
   1652   bool is_monomorphic_;
   1653   ZoneMapList* receiver_types_;
   1654   Handle<Map> monomorphic_receiver_type_;
   1655 };
   1656 
   1657 
   1658 class Throw: public Expression {
   1659  public:
   1660   Throw(Expression* exception, int pos)
   1661       : exception_(exception), pos_(pos) {}
   1662 
   1663   DECLARE_NODE_TYPE(Throw)
   1664 
   1665   Expression* exception() const { return exception_; }
   1666   virtual int position() const { return pos_; }
   1667   virtual bool IsInlineable() const;
   1668 
   1669  private:
   1670   Expression* exception_;
   1671   int pos_;
   1672 };
   1673 
   1674 
   1675 class FunctionLiteral: public Expression {
   1676  public:
   1677   FunctionLiteral(Handle<String> name,
   1678                   Scope* scope,
   1679                   ZoneList<Statement*>* body,
   1680                   int materialized_literal_count,
   1681                   int expected_property_count,
   1682                   bool has_only_simple_this_property_assignments,
   1683                   Handle<FixedArray> this_property_assignments,
   1684                   int num_parameters,
   1685                   int start_position,
   1686                   int end_position,
   1687                   bool is_expression)
   1688       : name_(name),
   1689         scope_(scope),
   1690         body_(body),
   1691         materialized_literal_count_(materialized_literal_count),
   1692         expected_property_count_(expected_property_count),
   1693         has_only_simple_this_property_assignments_(
   1694             has_only_simple_this_property_assignments),
   1695         this_property_assignments_(this_property_assignments),
   1696         num_parameters_(num_parameters),
   1697         start_position_(start_position),
   1698         end_position_(end_position),
   1699         is_expression_(is_expression),
   1700         function_token_position_(RelocInfo::kNoPosition),
   1701         inferred_name_(HEAP->empty_string()),
   1702         pretenure_(false) { }
   1703 
   1704   DECLARE_NODE_TYPE(FunctionLiteral)
   1705 
   1706   Handle<String> name() const { return name_; }
   1707   Scope* scope() const { return scope_; }
   1708   ZoneList<Statement*>* body() const { return body_; }
   1709   void set_function_token_position(int pos) { function_token_position_ = pos; }
   1710   int function_token_position() const { return function_token_position_; }
   1711   int start_position() const { return start_position_; }
   1712   int end_position() const { return end_position_; }
   1713   bool is_expression() const { return is_expression_; }
   1714   bool strict_mode() const;
   1715 
   1716   int materialized_literal_count() { return materialized_literal_count_; }
   1717   int expected_property_count() { return expected_property_count_; }
   1718   bool has_only_simple_this_property_assignments() {
   1719       return has_only_simple_this_property_assignments_;
   1720   }
   1721   Handle<FixedArray> this_property_assignments() {
   1722       return this_property_assignments_;
   1723   }
   1724   int num_parameters() { return num_parameters_; }
   1725 
   1726   bool AllowsLazyCompilation();
   1727 
   1728   Handle<String> debug_name() const {
   1729     if (name_->length() > 0) return name_;
   1730     return inferred_name();
   1731   }
   1732 
   1733   Handle<String> inferred_name() const { return inferred_name_; }
   1734   void set_inferred_name(Handle<String> inferred_name) {
   1735     inferred_name_ = inferred_name;
   1736   }
   1737 
   1738   bool pretenure() { return pretenure_; }
   1739   void set_pretenure(bool value) { pretenure_ = value; }
   1740   virtual bool IsInlineable() const;
   1741 
   1742  private:
   1743   Handle<String> name_;
   1744   Scope* scope_;
   1745   ZoneList<Statement*>* body_;
   1746   int materialized_literal_count_;
   1747   int expected_property_count_;
   1748   bool has_only_simple_this_property_assignments_;
   1749   Handle<FixedArray> this_property_assignments_;
   1750   int num_parameters_;
   1751   int start_position_;
   1752   int end_position_;
   1753   bool is_expression_;
   1754   int function_token_position_;
   1755   Handle<String> inferred_name_;
   1756   bool pretenure_;
   1757 };
   1758 
   1759 
   1760 class SharedFunctionInfoLiteral: public Expression {
   1761  public:
   1762   explicit SharedFunctionInfoLiteral(
   1763       Handle<SharedFunctionInfo> shared_function_info)
   1764       : shared_function_info_(shared_function_info) { }
   1765 
   1766   DECLARE_NODE_TYPE(SharedFunctionInfoLiteral)
   1767 
   1768   Handle<SharedFunctionInfo> shared_function_info() const {
   1769     return shared_function_info_;
   1770   }
   1771   virtual bool IsInlineable() const;
   1772 
   1773  private:
   1774   Handle<SharedFunctionInfo> shared_function_info_;
   1775 };
   1776 
   1777 
   1778 class ThisFunction: public Expression {
   1779  public:
   1780   DECLARE_NODE_TYPE(ThisFunction)
   1781   virtual bool IsInlineable() const;
   1782 };
   1783 
   1784 
   1785 // ----------------------------------------------------------------------------
   1786 // Regular expressions
   1787 
   1788 
   1789 class RegExpVisitor BASE_EMBEDDED {
   1790  public:
   1791   virtual ~RegExpVisitor() { }
   1792 #define MAKE_CASE(Name)                                              \
   1793   virtual void* Visit##Name(RegExp##Name*, void* data) = 0;
   1794   FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
   1795 #undef MAKE_CASE
   1796 };
   1797 
   1798 
   1799 class RegExpTree: public ZoneObject {
   1800  public:
   1801   static const int kInfinity = kMaxInt;
   1802   virtual ~RegExpTree() { }
   1803   virtual void* Accept(RegExpVisitor* visitor, void* data) = 0;
   1804   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
   1805                              RegExpNode* on_success) = 0;
   1806   virtual bool IsTextElement() { return false; }
   1807   virtual bool IsAnchoredAtStart() { return false; }
   1808   virtual bool IsAnchoredAtEnd() { return false; }
   1809   virtual int min_match() = 0;
   1810   virtual int max_match() = 0;
   1811   // Returns the interval of registers used for captures within this
   1812   // expression.
   1813   virtual Interval CaptureRegisters() { return Interval::Empty(); }
   1814   virtual void AppendToText(RegExpText* text);
   1815   SmartPointer<const char> ToString();
   1816 #define MAKE_ASTYPE(Name)                                                  \
   1817   virtual RegExp##Name* As##Name();                                        \
   1818   virtual bool Is##Name();
   1819   FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE)
   1820 #undef MAKE_ASTYPE
   1821 };
   1822 
   1823 
   1824 class RegExpDisjunction: public RegExpTree {
   1825  public:
   1826   explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives);
   1827   virtual void* Accept(RegExpVisitor* visitor, void* data);
   1828   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
   1829                              RegExpNode* on_success);
   1830   virtual RegExpDisjunction* AsDisjunction();
   1831   virtual Interval CaptureRegisters();
   1832   virtual bool IsDisjunction();
   1833   virtual bool IsAnchoredAtStart();
   1834   virtual bool IsAnchoredAtEnd();
   1835   virtual int min_match() { return min_match_; }
   1836   virtual int max_match() { return max_match_; }
   1837   ZoneList<RegExpTree*>* alternatives() { return alternatives_; }
   1838  private:
   1839   ZoneList<RegExpTree*>* alternatives_;
   1840   int min_match_;
   1841   int max_match_;
   1842 };
   1843 
   1844 
   1845 class RegExpAlternative: public RegExpTree {
   1846  public:
   1847   explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes);
   1848   virtual void* Accept(RegExpVisitor* visitor, void* data);
   1849   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
   1850                              RegExpNode* on_success);
   1851   virtual RegExpAlternative* AsAlternative();
   1852   virtual Interval CaptureRegisters();
   1853   virtual bool IsAlternative();
   1854   virtual bool IsAnchoredAtStart();
   1855   virtual bool IsAnchoredAtEnd();
   1856   virtual int min_match() { return min_match_; }
   1857   virtual int max_match() { return max_match_; }
   1858   ZoneList<RegExpTree*>* nodes() { return nodes_; }
   1859  private:
   1860   ZoneList<RegExpTree*>* nodes_;
   1861   int min_match_;
   1862   int max_match_;
   1863 };
   1864 
   1865 
   1866 class RegExpAssertion: public RegExpTree {
   1867  public:
   1868   enum Type {
   1869     START_OF_LINE,
   1870     START_OF_INPUT,
   1871     END_OF_LINE,
   1872     END_OF_INPUT,
   1873     BOUNDARY,
   1874     NON_BOUNDARY
   1875   };
   1876   explicit RegExpAssertion(Type type) : type_(type) { }
   1877   virtual void* Accept(RegExpVisitor* visitor, void* data);
   1878   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
   1879                              RegExpNode* on_success);
   1880   virtual RegExpAssertion* AsAssertion();
   1881   virtual bool IsAssertion();
   1882   virtual bool IsAnchoredAtStart();
   1883   virtual bool IsAnchoredAtEnd();
   1884   virtual int min_match() { return 0; }
   1885   virtual int max_match() { return 0; }
   1886   Type type() { return type_; }
   1887  private:
   1888   Type type_;
   1889 };
   1890 
   1891 
   1892 class CharacterSet BASE_EMBEDDED {
   1893  public:
   1894   explicit CharacterSet(uc16 standard_set_type)
   1895       : ranges_(NULL),
   1896         standard_set_type_(standard_set_type) {}
   1897   explicit CharacterSet(ZoneList<CharacterRange>* ranges)
   1898       : ranges_(ranges),
   1899         standard_set_type_(0) {}
   1900   ZoneList<CharacterRange>* ranges();
   1901   uc16 standard_set_type() { return standard_set_type_; }
   1902   void set_standard_set_type(uc16 special_set_type) {
   1903     standard_set_type_ = special_set_type;
   1904   }
   1905   bool is_standard() { return standard_set_type_ != 0; }
   1906   void Canonicalize();
   1907  private:
   1908   ZoneList<CharacterRange>* ranges_;
   1909   // If non-zero, the value represents a standard set (e.g., all whitespace
   1910   // characters) without having to expand the ranges.
   1911   uc16 standard_set_type_;
   1912 };
   1913 
   1914 
   1915 class RegExpCharacterClass: public RegExpTree {
   1916  public:
   1917   RegExpCharacterClass(ZoneList<CharacterRange>* ranges, bool is_negated)
   1918       : set_(ranges),
   1919         is_negated_(is_negated) { }
   1920   explicit RegExpCharacterClass(uc16 type)
   1921       : set_(type),
   1922         is_negated_(false) { }
   1923   virtual void* Accept(RegExpVisitor* visitor, void* data);
   1924   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
   1925                              RegExpNode* on_success);
   1926   virtual RegExpCharacterClass* AsCharacterClass();
   1927   virtual bool IsCharacterClass();
   1928   virtual bool IsTextElement() { return true; }
   1929   virtual int min_match() { return 1; }
   1930   virtual int max_match() { return 1; }
   1931   virtual void AppendToText(RegExpText* text);
   1932   CharacterSet character_set() { return set_; }
   1933   // TODO(lrn): Remove need for complex version if is_standard that
   1934   // recognizes a mangled standard set and just do { return set_.is_special(); }
   1935   bool is_standard();
   1936   // Returns a value representing the standard character set if is_standard()
   1937   // returns true.
   1938   // Currently used values are:
   1939   // s : unicode whitespace
   1940   // S : unicode non-whitespace
   1941   // w : ASCII word character (digit, letter, underscore)
   1942   // W : non-ASCII word character
   1943   // d : ASCII digit
   1944   // D : non-ASCII digit
   1945   // . : non-unicode non-newline
   1946   // * : All characters
   1947   uc16 standard_type() { return set_.standard_set_type(); }
   1948   ZoneList<CharacterRange>* ranges() { return set_.ranges(); }
   1949   bool is_negated() { return is_negated_; }
   1950  private:
   1951   CharacterSet set_;
   1952   bool is_negated_;
   1953 };
   1954 
   1955 
   1956 class RegExpAtom: public RegExpTree {
   1957  public:
   1958   explicit RegExpAtom(Vector<const uc16> data) : data_(data) { }
   1959   virtual void* Accept(RegExpVisitor* visitor, void* data);
   1960   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
   1961                              RegExpNode* on_success);
   1962   virtual RegExpAtom* AsAtom();
   1963   virtual bool IsAtom();
   1964   virtual bool IsTextElement() { return true; }
   1965   virtual int min_match() { return data_.length(); }
   1966   virtual int max_match() { return data_.length(); }
   1967   virtual void AppendToText(RegExpText* text);
   1968   Vector<const uc16> data() { return data_; }
   1969   int length() { return data_.length(); }
   1970  private:
   1971   Vector<const uc16> data_;
   1972 };
   1973 
   1974 
   1975 class RegExpText: public RegExpTree {
   1976  public:
   1977   RegExpText() : elements_(2), length_(0) {}
   1978   virtual void* Accept(RegExpVisitor* visitor, void* data);
   1979   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
   1980                              RegExpNode* on_success);
   1981   virtual RegExpText* AsText();
   1982   virtual bool IsText();
   1983   virtual bool IsTextElement() { return true; }
   1984   virtual int min_match() { return length_; }
   1985   virtual int max_match() { return length_; }
   1986   virtual void AppendToText(RegExpText* text);
   1987   void AddElement(TextElement elm)  {
   1988     elements_.Add(elm);
   1989     length_ += elm.length();
   1990   }
   1991   ZoneList<TextElement>* elements() { return &elements_; }
   1992  private:
   1993   ZoneList<TextElement> elements_;
   1994   int length_;
   1995 };
   1996 
   1997 
   1998 class RegExpQuantifier: public RegExpTree {
   1999  public:
   2000   enum Type { GREEDY, NON_GREEDY, POSSESSIVE };
   2001   RegExpQuantifier(int min, int max, Type type, RegExpTree* body)
   2002       : body_(body),
   2003         min_(min),
   2004         max_(max),
   2005         min_match_(min * body->min_match()),
   2006         type_(type) {
   2007     if (max > 0 && body->max_match() > kInfinity / max) {
   2008       max_match_ = kInfinity;
   2009     } else {
   2010       max_match_ = max * body->max_match();
   2011     }
   2012   }
   2013   virtual void* Accept(RegExpVisitor* visitor, void* data);
   2014   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
   2015                              RegExpNode* on_success);
   2016   static RegExpNode* ToNode(int min,
   2017                             int max,
   2018                             bool is_greedy,
   2019                             RegExpTree* body,
   2020                             RegExpCompiler* compiler,
   2021                             RegExpNode* on_success,
   2022                             bool not_at_start = false);
   2023   virtual RegExpQuantifier* AsQuantifier();
   2024   virtual Interval CaptureRegisters();
   2025   virtual bool IsQuantifier();
   2026   virtual int min_match() { return min_match_; }
   2027   virtual int max_match() { return max_match_; }
   2028   int min() { return min_; }
   2029   int max() { return max_; }
   2030   bool is_possessive() { return type_ == POSSESSIVE; }
   2031   bool is_non_greedy() { return type_ == NON_GREEDY; }
   2032   bool is_greedy() { return type_ == GREEDY; }
   2033   RegExpTree* body() { return body_; }
   2034  private:
   2035   RegExpTree* body_;
   2036   int min_;
   2037   int max_;
   2038   int min_match_;
   2039   int max_match_;
   2040   Type type_;
   2041 };
   2042 
   2043 
   2044 class RegExpCapture: public RegExpTree {
   2045  public:
   2046   explicit RegExpCapture(RegExpTree* body, int index)
   2047       : body_(body), index_(index) { }
   2048   virtual void* Accept(RegExpVisitor* visitor, void* data);
   2049   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
   2050                              RegExpNode* on_success);
   2051   static RegExpNode* ToNode(RegExpTree* body,
   2052                             int index,
   2053                             RegExpCompiler* compiler,
   2054                             RegExpNode* on_success);
   2055   virtual RegExpCapture* AsCapture();
   2056   virtual bool IsAnchoredAtStart();
   2057   virtual bool IsAnchoredAtEnd();
   2058   virtual Interval CaptureRegisters();
   2059   virtual bool IsCapture();
   2060   virtual int min_match() { return body_->min_match(); }
   2061   virtual int max_match() { return body_->max_match(); }
   2062   RegExpTree* body() { return body_; }
   2063   int index() { return index_; }
   2064   static int StartRegister(int index) { return index * 2; }
   2065   static int EndRegister(int index) { return index * 2 + 1; }
   2066  private:
   2067   RegExpTree* body_;
   2068   int index_;
   2069 };
   2070 
   2071 
   2072 class RegExpLookahead: public RegExpTree {
   2073  public:
   2074   RegExpLookahead(RegExpTree* body,
   2075                   bool is_positive,
   2076                   int capture_count,
   2077                   int capture_from)
   2078       : body_(body),
   2079         is_positive_(is_positive),
   2080         capture_count_(capture_count),
   2081         capture_from_(capture_from) { }
   2082 
   2083   virtual void* Accept(RegExpVisitor* visitor, void* data);
   2084   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
   2085                              RegExpNode* on_success);
   2086   virtual RegExpLookahead* AsLookahead();
   2087   virtual Interval CaptureRegisters();
   2088   virtual bool IsLookahead();
   2089   virtual bool IsAnchoredAtStart();
   2090   virtual int min_match() { return 0; }
   2091   virtual int max_match() { return 0; }
   2092   RegExpTree* body() { return body_; }
   2093   bool is_positive() { return is_positive_; }
   2094   int capture_count() { return capture_count_; }
   2095   int capture_from() { return capture_from_; }
   2096  private:
   2097   RegExpTree* body_;
   2098   bool is_positive_;
   2099   int capture_count_;
   2100   int capture_from_;
   2101 };
   2102 
   2103 
   2104 class RegExpBackReference: public RegExpTree {
   2105  public:
   2106   explicit RegExpBackReference(RegExpCapture* capture)
   2107       : capture_(capture) { }
   2108   virtual void* Accept(RegExpVisitor* visitor, void* data);
   2109   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
   2110                              RegExpNode* on_success);
   2111   virtual RegExpBackReference* AsBackReference();
   2112   virtual bool IsBackReference();
   2113   virtual int min_match() { return 0; }
   2114   virtual int max_match() { return capture_->max_match(); }
   2115   int index() { return capture_->index(); }
   2116   RegExpCapture* capture() { return capture_; }
   2117  private:
   2118   RegExpCapture* capture_;
   2119 };
   2120 
   2121 
   2122 class RegExpEmpty: public RegExpTree {
   2123  public:
   2124   RegExpEmpty() { }
   2125   virtual void* Accept(RegExpVisitor* visitor, void* data);
   2126   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
   2127                              RegExpNode* on_success);
   2128   virtual RegExpEmpty* AsEmpty();
   2129   virtual bool IsEmpty();
   2130   virtual int min_match() { return 0; }
   2131   virtual int max_match() { return 0; }
   2132   static RegExpEmpty* GetInstance() { return &kInstance; }
   2133  private:
   2134   static RegExpEmpty kInstance;
   2135 };
   2136 
   2137 
   2138 // ----------------------------------------------------------------------------
   2139 // Basic visitor
   2140 // - leaf node visitors are abstract.
   2141 
   2142 class AstVisitor BASE_EMBEDDED {
   2143  public:
   2144   AstVisitor() : isolate_(Isolate::Current()), stack_overflow_(false) { }
   2145   virtual ~AstVisitor() { }
   2146 
   2147   // Stack overflow check and dynamic dispatch.
   2148   void Visit(AstNode* node) { if (!CheckStackOverflow()) node->Accept(this); }
   2149 
   2150   // Iteration left-to-right.
   2151   virtual void VisitDeclarations(ZoneList<Declaration*>* declarations);
   2152   virtual void VisitStatements(ZoneList<Statement*>* statements);
   2153   virtual void VisitExpressions(ZoneList<Expression*>* expressions);
   2154 
   2155   // Stack overflow tracking support.
   2156   bool HasStackOverflow() const { return stack_overflow_; }
   2157   bool CheckStackOverflow();
   2158 
   2159   // If a stack-overflow exception is encountered when visiting a
   2160   // node, calling SetStackOverflow will make sure that the visitor
   2161   // bails out without visiting more nodes.
   2162   void SetStackOverflow() { stack_overflow_ = true; }
   2163   void ClearStackOverflow() { stack_overflow_ = false; }
   2164 
   2165   // Nodes not appearing in the AST, including slots.
   2166   virtual void VisitSlot(Slot* node) { UNREACHABLE(); }
   2167 
   2168   // Individual AST nodes.
   2169 #define DEF_VISIT(type)                         \
   2170   virtual void Visit##type(type* node) = 0;
   2171   AST_NODE_LIST(DEF_VISIT)
   2172 #undef DEF_VISIT
   2173 
   2174  protected:
   2175   Isolate* isolate() { return isolate_; }
   2176 
   2177  private:
   2178   Isolate* isolate_;
   2179   bool stack_overflow_;
   2180 };
   2181 
   2182 
   2183 } }  // namespace v8::internal
   2184 
   2185 #endif  // V8_AST_H_
   2186