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