• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
~AstNode()120   virtual ~AstNode() { }
121   virtual void Accept(AstVisitor* v) = 0;
122 
123   // Type testing & conversion.
AsStatement()124   virtual Statement* AsStatement() { return NULL; }
AsExpressionStatement()125   virtual ExpressionStatement* AsExpressionStatement() { return NULL; }
AsEmptyStatement()126   virtual EmptyStatement* AsEmptyStatement() { return NULL; }
AsExpression()127   virtual Expression* AsExpression() { return NULL; }
AsLiteral()128   virtual Literal* AsLiteral() { return NULL; }
AsSlot()129   virtual Slot* AsSlot() { return NULL; }
AsVariableProxy()130   virtual VariableProxy* AsVariableProxy() { return NULL; }
AsProperty()131   virtual Property* AsProperty() { return NULL; }
AsCall()132   virtual Call* AsCall() { return NULL; }
AsTargetCollector()133   virtual TargetCollector* AsTargetCollector() { return NULL; }
AsBreakableStatement()134   virtual BreakableStatement* AsBreakableStatement() { return NULL; }
AsIterationStatement()135   virtual IterationStatement* AsIterationStatement() { return NULL; }
AsUnaryOperation()136   virtual UnaryOperation* AsUnaryOperation() { return NULL; }
AsBinaryOperation()137   virtual BinaryOperation* AsBinaryOperation() { return NULL; }
AsAssignment()138   virtual Assignment* AsAssignment() { return NULL; }
AsFunctionLiteral()139   virtual FunctionLiteral* AsFunctionLiteral() { return NULL; }
AsMaterializedLiteral()140   virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; }
AsObjectLiteral()141   virtual ObjectLiteral* AsObjectLiteral() { return NULL; }
AsArrayLiteral()142   virtual ArrayLiteral* AsArrayLiteral() { return NULL; }
AsCompareOperation()143   virtual CompareOperation* AsCompareOperation() { return NULL; }
144 };
145 
146 
147 class Statement: public AstNode {
148  public:
Statement()149   Statement() : statement_pos_(RelocInfo::kNoPosition) {}
150 
AsStatement()151   virtual Statement* AsStatement()  { return this; }
AsReturnStatement()152   virtual ReturnStatement* AsReturnStatement() { return NULL; }
153 
IsEmpty()154   bool IsEmpty() { return AsEmptyStatement() != NULL; }
155 
set_statement_pos(int statement_pos)156   void set_statement_pos(int statement_pos) { 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 
Expression()186   Expression() : num_(kNoLabel), def_(NULL), defined_vars_(NULL) {}
187 
AsExpression()188   virtual Expression* AsExpression()  { return this; }
189 
IsValidLeftHandSide()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.
IsPropertyName()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.
IsLeaf()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.
IsTrivial()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.
MarkAsStatement()209   virtual void MarkAsStatement() { /* do nothing */ }
210 
211   // Static type information for this expression.
type()212   StaticType* type() { return &type_; }
213 
num()214   int num() { return num_; }
215 
216   // AST node numbering ordered by evaluation order.
set_num(int n)217   void set_num(int n) { num_ = n; }
218 
219   // Data flow information.
var_def()220   DefinitionInfo* var_def() { return def_; }
set_var_def(DefinitionInfo * def)221   void set_var_def(DefinitionInfo* def) { def_ = def; }
222 
defined_vars()223   ZoneList<DefinitionInfo*>* defined_vars() { return defined_vars_; }
set_defined_vars(ZoneList<DefinitionInfo * > * 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:
IsValidLeftHandSide()243   virtual bool IsValidLeftHandSide() { return true; }
Accept(AstVisitor * v)244   virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
instance()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.
labels()260   ZoneStringList* labels() const { return labels_; }
261 
262   // Type testing & conversion.
AsBreakableStatement()263   virtual BreakableStatement* AsBreakableStatement() { return this; }
264 
265   // Code generation
break_target()266   BreakTarget* break_target() { return &break_target_; }
267 
268   // Testers.
is_target_for_anonymous()269   bool is_target_for_anonymous() const { return type_ == TARGET_FOR_ANONYMOUS; }
270 
271  protected:
BreakableStatement(ZoneStringList * labels,Type type)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:
Block(ZoneStringList * labels,int capacity,bool is_initializer_block)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 
AddStatement(Statement * statement)293   void AddStatement(Statement* statement) { statements_.Add(statement); }
294 
statements()295   ZoneList<Statement*>* statements() { return &statements_; }
is_initializer_block()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:
Declaration(VariableProxy * proxy,Variable::Mode mode,FunctionLiteral * fun)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 
proxy()317   VariableProxy* proxy() const  { return proxy_; }
mode()318   Variable::Mode mode() const  { return mode_; }
fun()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.
AsIterationStatement()331   virtual IterationStatement* AsIterationStatement() { return this; }
332 
body()333   Statement* body() const { return body_; }
334 
335   // Code generation
continue_target()336   BreakTarget* continue_target()  { return &continue_target_; }
337 
338  protected:
IterationStatement(ZoneStringList * labels)339   explicit IterationStatement(ZoneStringList* labels)
340       : BreakableStatement(labels, TARGET_FOR_ANONYMOUS), body_(NULL) { }
341 
Initialize(Statement * body)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:
DoWhileStatement(ZoneStringList * labels)354   explicit DoWhileStatement(ZoneStringList* labels)
355       : IterationStatement(labels), cond_(NULL), condition_position_(-1) {
356   }
357 
Initialize(Expression * cond,Statement * body)358   void Initialize(Expression* cond, Statement* body) {
359     IterationStatement::Initialize(body);
360     cond_ = cond;
361   }
362 
363   virtual void Accept(AstVisitor* v);
364 
cond()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.
condition_position()369   int condition_position() { return condition_position_; }
set_condition_position(int pos)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:
WhileStatement(ZoneStringList * labels)380   explicit WhileStatement(ZoneStringList* labels)
381       : IterationStatement(labels),
382         cond_(NULL),
383         may_have_function_literal_(true) {
384   }
385 
Initialize(Expression * cond,Statement * body)386   void Initialize(Expression* cond, Statement* body) {
387     IterationStatement::Initialize(body);
388     cond_ = cond;
389   }
390 
391   virtual void Accept(AstVisitor* v);
392 
cond()393   Expression* cond() const { return cond_; }
may_have_function_literal()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:
ForStatement(ZoneStringList * labels)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 
Initialize(Statement * init,Expression * cond,Statement * next,Statement * body)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 
init()429   Statement* init() const  { return init_; }
cond()430   Expression* cond() const  { return cond_; }
next()431   Statement* next() const  { return next_; }
may_have_function_literal()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:
ForInStatement(ZoneStringList * labels)449   explicit ForInStatement(ZoneStringList* labels)
450       : IterationStatement(labels), each_(NULL), enumerable_(NULL) { }
451 
Initialize(Expression * each,Expression * enumerable,Statement * body)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 
each()460   Expression* each() const { return each_; }
enumerable()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:
ExpressionStatement(Expression * expression)471   explicit ExpressionStatement(Expression* expression)
472       : expression_(expression) { }
473 
474   virtual void Accept(AstVisitor* v);
475 
476   // Type testing & conversion.
AsExpressionStatement()477   virtual ExpressionStatement* AsExpressionStatement() { return this; }
478 
set_expression(Expression * e)479   void set_expression(Expression* e) { expression_ = e; }
expression()480   Expression* expression() { return expression_; }
481 
482  private:
483   Expression* expression_;
484 };
485 
486 
487 class ContinueStatement: public Statement {
488  public:
ContinueStatement(IterationStatement * target)489   explicit ContinueStatement(IterationStatement* target)
490       : target_(target) { }
491 
492   virtual void Accept(AstVisitor* v);
493 
target()494   IterationStatement* target() const  { return target_; }
495 
496  private:
497   IterationStatement* target_;
498 };
499 
500 
501 class BreakStatement: public Statement {
502  public:
BreakStatement(BreakableStatement * target)503   explicit BreakStatement(BreakableStatement* target)
504       : target_(target) { }
505 
506   virtual void Accept(AstVisitor* v);
507 
target()508   BreakableStatement* target() const  { return target_; }
509 
510  private:
511   BreakableStatement* target_;
512 };
513 
514 
515 class ReturnStatement: public Statement {
516  public:
ReturnStatement(Expression * expression)517   explicit ReturnStatement(Expression* expression)
518       : expression_(expression) { }
519 
520   virtual void Accept(AstVisitor* v);
521 
522   // Type testing & conversion.
AsReturnStatement()523   virtual ReturnStatement* AsReturnStatement() { return this; }
524 
expression()525   Expression* expression() { return expression_; }
526 
527  private:
528   Expression* expression_;
529 };
530 
531 
532 class WithEnterStatement: public Statement {
533  public:
WithEnterStatement(Expression * expression,bool is_catch_block)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 
expression()539   Expression* expression() const  { return expression_; }
540 
is_catch_block()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:
WithExitStatement()551   WithExitStatement() { }
552 
553   virtual void Accept(AstVisitor* v);
554 };
555 
556 
557 class CaseClause: public ZoneObject {
558  public:
CaseClause(Expression * label,ZoneList<Statement * > * statements)559   CaseClause(Expression* label, ZoneList<Statement*>* statements)
560       : label_(label), statements_(statements) { }
561 
is_default()562   bool is_default() const  { return label_ == NULL; }
label()563   Expression* label() const  {
564     CHECK(!is_default());
565     return label_;
566   }
body_target()567   JumpTarget* body_target() { return &body_target_; }
statements()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:
SwitchStatement(ZoneStringList * labels)579   explicit SwitchStatement(ZoneStringList* labels)
580       : BreakableStatement(labels, TARGET_FOR_ANONYMOUS),
581         tag_(NULL), cases_(NULL) { }
582 
Initialize(Expression * tag,ZoneList<CaseClause * > * cases)583   void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) {
584     tag_ = tag;
585     cases_ = cases;
586   }
587 
588   virtual void Accept(AstVisitor* v);
589 
tag()590   Expression* tag() const  { return tag_; }
cases()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:
IfStatement(Expression * condition,Statement * then_statement,Statement * else_statement)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 
HasThenStatement()615   bool HasThenStatement() const { return !then_statement()->IsEmpty(); }
HasElseStatement()616   bool HasElseStatement() const { return !else_statement()->IsEmpty(); }
617 
condition()618   Expression* condition() const { return condition_; }
then_statement()619   Statement* then_statement() const { return then_statement_; }
else_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:
TargetCollector(ZoneList<BreakTarget * > * targets)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.
Accept(AstVisitor * v)643   virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
AsTargetCollector()644   virtual TargetCollector* AsTargetCollector() { return this; }
645 
targets()646   ZoneList<BreakTarget*>* targets() { return targets_; }
647 
648  private:
649   ZoneList<BreakTarget*>* targets_;
650 };
651 
652 
653 class TryStatement: public Statement {
654  public:
TryStatement(Block * try_block)655   explicit TryStatement(Block* try_block)
656       : try_block_(try_block), escaping_targets_(NULL) { }
657 
set_escaping_targets(ZoneList<BreakTarget * > * targets)658   void set_escaping_targets(ZoneList<BreakTarget*>* targets) {
659     escaping_targets_ = targets;
660   }
661 
try_block()662   Block* try_block() const { return try_block_; }
escaping_targets()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:
TryCatchStatement(Block * try_block,VariableProxy * catch_var,Block * catch_block)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 
catch_var()683   VariableProxy* catch_var() const  { return catch_var_; }
catch_block()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:
TryFinallyStatement(Block * try_block,Block * finally_block)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 
finally_block()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.
AsEmptyStatement()718   virtual EmptyStatement* AsEmptyStatement() { return this; }
719 };
720 
721 
722 class Literal: public Expression {
723  public:
Literal(Handle<Object> handle)724   explicit Literal(Handle<Object> handle) : handle_(handle) { }
725 
726   virtual void Accept(AstVisitor* v);
727 
728   // Type testing & conversion.
AsLiteral()729   virtual Literal* AsLiteral() { return this; }
730 
731   // Check if this literal is identical to the other literal.
IsIdenticalTo(const Literal * other)732   bool IsIdenticalTo(const Literal* other) const {
733     return handle_.is_identical_to(other->handle_);
734   }
735 
IsPropertyName()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 
IsLeaf()744   virtual bool IsLeaf() { return true; }
IsTrivial()745   virtual bool IsTrivial() { return true; }
746 
747   // Identity testers.
IsNull()748   bool IsNull() const { return handle_.is_identical_to(Factory::null_value()); }
IsTrue()749   bool IsTrue() const { return handle_.is_identical_to(Factory::true_value()); }
IsFalse()750   bool IsFalse() const {
751     return handle_.is_identical_to(Factory::false_value());
752   }
753 
handle()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:
MaterializedLiteral(int literal_index,bool is_simple,int depth)764   explicit MaterializedLiteral(int literal_index, bool is_simple, int depth)
765       : literal_index_(literal_index), is_simple_(is_simple), depth_(depth) {}
766 
AsMaterializedLiteral()767   virtual MaterializedLiteral* AsMaterializedLiteral() { return this; }
768 
literal_index()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.
is_simple()773   bool is_simple() const { return is_simple_; }
774 
depth()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 
key()805     Literal* key() { return key_; }
value()806     Expression* value() { return value_; }
kind()807     Kind kind() { return kind_; }
808 
809     bool IsCompileTimeValue();
810 
811    private:
812     Literal* key_;
813     Expression* value_;
814     Kind kind_;
815   };
816 
ObjectLiteral(Handle<FixedArray> constant_properties,ZoneList<Property * > * properties,int literal_index,bool is_simple,int depth)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 
AsObjectLiteral()826   virtual ObjectLiteral* AsObjectLiteral() { return this; }
827   virtual void Accept(AstVisitor* v);
828 
IsLeaf()829   virtual bool IsLeaf() { return properties()->is_empty(); }
830 
constant_properties()831   Handle<FixedArray> constant_properties() const {
832     return constant_properties_;
833   }
properties()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:
RegExpLiteral(Handle<String> pattern,Handle<String> flags,int literal_index)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 
IsLeaf()854   virtual bool IsLeaf() { return true; }
855 
pattern()856   Handle<String> pattern() const { return pattern_; }
flags()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:
ArrayLiteral(Handle<FixedArray> constant_elements,ZoneList<Expression * > * values,int literal_index,bool is_simple,int depth)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);
AsArrayLiteral()878   virtual ArrayLiteral* AsArrayLiteral() { return this; }
879 
IsLeaf()880   virtual bool IsLeaf() { return values()->is_empty(); }
881 
constant_elements()882   Handle<FixedArray> constant_elements() const { return constant_elements_; }
values()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:
CatchExtensionObject(Literal * key,VariableProxy * value)896   CatchExtensionObject(Literal* key, VariableProxy* value)
897       : key_(key), value_(value) {
898   }
899 
900   virtual void Accept(AstVisitor* v);
901 
key()902   Literal* key() const { return key_; }
value()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
AsProperty()916   virtual Property* AsProperty() {
917     return var_ == NULL ? NULL : var_->AsProperty();
918   }
AsVariableProxy()919   virtual VariableProxy* AsVariableProxy()  { return this; }
920 
AsVariable()921   Variable* AsVariable() {
922     return this == NULL || var_ == NULL ? NULL : var_->AsVariable();
923   }
924 
IsValidLeftHandSide()925   virtual bool IsValidLeftHandSide() {
926     return var_ == NULL ? true : var_->IsValidLeftHandSide();
927   }
928 
IsLeaf()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.
IsTrivial()936   virtual bool IsTrivial() { return is_this(); }
937 
IsVariable(Handle<String> n)938   bool IsVariable(Handle<String> n) {
939     return !is_this() && name().is_identical_to(n);
940   }
941 
IsArguments()942   bool IsArguments() {
943     Variable* variable = AsVariable();
944     return (variable == NULL) ? false : variable->is_arguments();
945   }
946 
name()947   Handle<String> name() const  { return name_; }
var()948   Variable* var() const  { return var_; }
var_uses()949   UseCount* var_uses()  { return &var_uses_; }
obj_uses()950   UseCount* obj_uses()  { return &obj_uses_; }
is_this()951   bool is_this() const  { return is_this_; }
inside_with()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:
IsValidLeftHandSide()976   virtual bool IsValidLeftHandSide() { return !is_this(); }
this_proxy()977   static VariableProxySentinel* this_proxy() { return &this_proxy_; }
identifier_proxy()978   static VariableProxySentinel* identifier_proxy() {
979     return &identifier_proxy_;
980   }
981 
982  private:
VariableProxySentinel(bool is_this)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 
Slot(Variable * var,Type type,int index)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
AsSlot()1021   virtual Slot* AsSlot() { return this; }
1022 
IsLeaf()1023   virtual bool IsLeaf() { return true; }
1024 
1025   // Accessors
var()1026   Variable* var() const { return var_; }
type()1027   Type type() const { return type_; }
index()1028   int index() const { return index_; }
is_arguments()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)
obj_(obj)1046       : obj_(obj), key_(key), pos_(pos), type_(type) { }
1047 
1048   virtual void Accept(AstVisitor* v);
1049 
1050   // Type testing & conversion
AsProperty()1051   virtual Property* AsProperty() { return this; }
1052 
IsValidLeftHandSide()1053   virtual bool IsValidLeftHandSide() { return true; }
1054 
obj()1055   Expression* obj() const { return obj_; }
key()1056   Expression* key() const { return key_; }
position()1057   int position() const { return pos_; }
is_synthetic()1058   bool is_synthetic() const { return type_ == SYNTHETIC; }
1059 
1060   // Returns a property singleton property access on 'this'.  Used
1061   // during preparsing.
this_property()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:
Call(Expression * expression,ZoneList<Expression * > * arguments,int pos)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.
AsCall()1083   virtual Call* AsCall() { return this; }
1084 
expression()1085   Expression* expression() const { return expression_; }
arguments()1086   ZoneList<Expression*>* arguments() const { return arguments_; }
position()1087   int position() { return pos_; }
1088 
sentinel()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:
CallNew(Expression * expression,ZoneList<Expression * > * arguments,int pos)1102   CallNew(Expression* expression, ZoneList<Expression*>* arguments, int pos)
1103       : expression_(expression), arguments_(arguments), pos_(pos) { }
1104 
1105   virtual void Accept(AstVisitor* v);
1106 
expression()1107   Expression* expression() const { return expression_; }
arguments()1108   ZoneList<Expression*>* arguments() const { return arguments_; }
position()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:
CallRuntime(Handle<String> name,Runtime::Function * function,ZoneList<Expression * > * arguments)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 
name()1131   Handle<String> name() const { return name_; }
function()1132   Runtime::Function* function() const { return function_; }
arguments()1133   ZoneList<Expression*>* arguments() const { return arguments_; }
is_jsruntime()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:
UnaryOperation(Token::Value op,Expression * expression)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
AsUnaryOperation()1153   virtual UnaryOperation* AsUnaryOperation() { return this; }
1154 
op()1155   Token::Value op() const { return op_; }
expression()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:
BinaryOperation(Token::Value op,Expression * left,Expression * right)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
AsBinaryOperation()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.
ResultOverwriteAllowed()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 
op()1202   Token::Value op() const { return op_; }
left()1203   Expression* left() const { return left_; }
right()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:
CountOperation(bool is_prefix,Token::Value op,Expression * expression)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 
is_prefix()1222   bool is_prefix() const { return is_prefix_; }
is_postfix()1223   bool is_postfix() const { return !is_prefix_; }
op()1224   Token::Value op() const { return op_; }
binary_op()1225   Token::Value binary_op() {
1226     return op_ == Token::INC ? Token::ADD : Token::SUB;
1227   }
expression()1228   Expression* expression() const { return expression_; }
1229 
MarkAsStatement()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:
CompareOperation(Token::Value op,Expression * left,Expression * right)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 
op()1248   Token::Value op() const { return op_; }
left()1249   Expression* left() const { return left_; }
right()1250   Expression* right() const { return right_; }
1251 
1252   // Accessors for flag whether this compare operation is hanging of a for loop.
is_for_loop_condition()1253   bool is_for_loop_condition() const { return is_for_loop_condition_; }
set_is_for_loop_condition()1254   void set_is_for_loop_condition() { is_for_loop_condition_ = true; }
1255 
1256   // Type testing & conversion
AsCompareOperation()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:
Conditional(Expression * condition,Expression * then_expression,Expression * else_expression)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 
condition()1278   Expression* condition() const { return condition_; }
then_expression()1279   Expression* then_expression() const { return then_expression_; }
else_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:
Assignment(Token::Value op,Expression * target,Expression * value,int pos)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);
AsAssignment()1298   virtual Assignment* AsAssignment() { return this; }
1299 
1300   Token::Value binary_op() const;
1301 
op()1302   Token::Value op() const { return op_; }
target()1303   Expression* target() const { return target_; }
value()1304   Expression* value() const { return value_; }
position()1305   int position() { return pos_; }
1306   // This check relies on the definition order of token in token.h.
is_compound()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.
starts_initialization_block()1313   bool starts_initialization_block() { return block_start_; }
ends_initialization_block()1314   bool ends_initialization_block() { return block_end_; }
mark_block_start()1315   void mark_block_start() { block_start_ = true; }
mark_block_end()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:
Throw(Expression * exception,int pos)1330   Throw(Expression* exception, int pos)
1331       : exception_(exception), pos_(pos) {}
1332 
1333   virtual void Accept(AstVisitor* v);
exception()1334   Expression* exception() const { return exception_; }
position()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:
FunctionLiteral(Handle<String> name,Scope * scope,ZoneList<Statement * > * body,int materialized_literal_count,int expected_property_count,bool has_only_simple_this_property_assignments,Handle<FixedArray> this_property_assignments,int num_parameters,int start_position,int end_position,bool is_expression)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
AsFunctionLiteral()1379   virtual FunctionLiteral* AsFunctionLiteral()  { return this; }
1380 
IsLeaf()1381   virtual bool IsLeaf() { return true; }
1382 
name()1383   Handle<String> name() const  { return name_; }
scope()1384   Scope* scope() const  { return scope_; }
body()1385   ZoneList<Statement*>* body() const  { return body_; }
set_function_token_position(int pos)1386   void set_function_token_position(int pos) { function_token_position_ = pos; }
function_token_position()1387   int function_token_position() const { return function_token_position_; }
start_position()1388   int start_position() const { return start_position_; }
end_position()1389   int end_position() const { return end_position_; }
is_expression()1390   bool is_expression() const { return is_expression_; }
1391 
materialized_literal_count()1392   int materialized_literal_count() { return materialized_literal_count_; }
expected_property_count()1393   int expected_property_count() { return expected_property_count_; }
has_only_simple_this_property_assignments()1394   bool has_only_simple_this_property_assignments() {
1395       return has_only_simple_this_property_assignments_;
1396   }
this_property_assignments()1397   Handle<FixedArray> this_property_assignments() {
1398       return this_property_assignments_;
1399   }
num_parameters()1400   int num_parameters() { return num_parameters_; }
1401 
1402   bool AllowsLazyCompilation();
1403 
inferred_name()1404   Handle<String> inferred_name() const  { return inferred_name_; }
set_inferred_name(Handle<String> inferred_name)1405   void set_inferred_name(Handle<String> inferred_name) {
1406     inferred_name_ = inferred_name;
1407   }
1408 
try_full_codegen()1409   bool try_full_codegen() { return try_full_codegen_; }
set_try_full_codegen(bool flag)1410   void set_try_full_codegen(bool flag) { try_full_codegen_ = flag; }
1411 
1412 #ifdef DEBUG
mark_as_compiled()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:
FunctionBoilerplateLiteral(Handle<JSFunction> boilerplate)1442   explicit FunctionBoilerplateLiteral(Handle<JSFunction> boilerplate)
1443       : boilerplate_(boilerplate) {
1444     ASSERT(boilerplate->IsBoilerplate());
1445   }
1446 
boilerplate()1447   Handle<JSFunction> boilerplate() const { return boilerplate_; }
1448 
IsLeaf()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);
IsLeaf()1461   virtual bool IsLeaf() { return true; }
1462 };
1463 
1464 
1465 // ----------------------------------------------------------------------------
1466 // Regular expressions
1467 
1468 
1469 class RegExpVisitor BASE_EMBEDDED {
1470  public:
~RegExpVisitor()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;
~RegExpTree()1482   virtual ~RegExpTree() { }
1483   virtual void* Accept(RegExpVisitor* visitor, void* data) = 0;
1484   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
1485                              RegExpNode* on_success) = 0;
IsTextElement()1486   virtual bool IsTextElement() { return false; }
IsAnchored()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.
CaptureRegisters()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();
min_match()1513   virtual int min_match() { return min_match_; }
max_match()1514   virtual int max_match() { return max_match_; }
alternatives()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();
min_match()1533   virtual int min_match() { return min_match_; }
max_match()1534   virtual int max_match() { return max_match_; }
nodes()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   };
RegExpAssertion(Type type)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();
min_match()1560   virtual int min_match() { return 0; }
max_match()1561   virtual int max_match() { return 0; }
type()1562   Type type() { return type_; }
1563  private:
1564   Type type_;
1565 };
1566 
1567 
1568 class CharacterSet BASE_EMBEDDED {
1569  public:
CharacterSet(uc16 standard_set_type)1570   explicit CharacterSet(uc16 standard_set_type)
1571       : ranges_(NULL),
1572         standard_set_type_(standard_set_type) {}
CharacterSet(ZoneList<CharacterRange> * ranges)1573   explicit CharacterSet(ZoneList<CharacterRange>* ranges)
1574       : ranges_(ranges),
1575         standard_set_type_(0) {}
1576   ZoneList<CharacterRange>* ranges();
standard_set_type()1577   uc16 standard_set_type() { return standard_set_type_; }
set_standard_set_type(uc16 special_set_type)1578   void set_standard_set_type(uc16 special_set_type) {
1579     standard_set_type_ = special_set_type;
1580   }
is_standard()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:
RegExpCharacterClass(ZoneList<CharacterRange> * ranges,bool is_negated)1593   RegExpCharacterClass(ZoneList<CharacterRange>* ranges, bool is_negated)
1594       : set_(ranges),
1595         is_negated_(is_negated) { }
RegExpCharacterClass(uc16 type)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();
IsTextElement()1604   virtual bool IsTextElement() { return true; }
min_match()1605   virtual int min_match() { return 1; }
max_match()1606   virtual int max_match() { return 1; }
1607   virtual void AppendToText(RegExpText* text);
character_set()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
standard_type()1623   uc16 standard_type() { return set_.standard_set_type(); }
ranges()1624   ZoneList<CharacterRange>* ranges() { return set_.ranges(); }
is_negated()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:
RegExpAtom(Vector<const uc16> data)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();
IsTextElement()1640   virtual bool IsTextElement() { return true; }
min_match()1641   virtual int min_match() { return data_.length(); }
max_match()1642   virtual int max_match() { return data_.length(); }
1643   virtual void AppendToText(RegExpText* text);
data()1644   Vector<const uc16> data() { return data_; }
length()1645   int length() { return data_.length(); }
1646  private:
1647   Vector<const uc16> data_;
1648 };
1649 
1650 
1651 class RegExpText: public RegExpTree {
1652  public:
RegExpText()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();
IsTextElement()1659   virtual bool IsTextElement() { return true; }
min_match()1660   virtual int min_match() { return length_; }
max_match()1661   virtual int max_match() { return length_; }
1662   virtual void AppendToText(RegExpText* text);
AddElement(TextElement elm)1663   void AddElement(TextElement elm)  {
1664     elements_.Add(elm);
1665     length_ += elm.length();
1666   };
elements()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 };
RegExpQuantifier(int min,int max,Type type,RegExpTree * body)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();
min_match()1702   virtual int min_match() { return min_match_; }
max_match()1703   virtual int max_match() { return max_match_; }
min()1704   int min() { return min_; }
max()1705   int max() { return max_; }
is_possessive()1706   bool is_possessive() { return type_ == POSSESSIVE; }
is_non_greedy()1707   bool is_non_greedy() { return type_ == NON_GREEDY; }
is_greedy()1708   bool is_greedy() { return type_ == GREEDY; }
body()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:
RegExpCapture(RegExpTree * body,int index)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();
min_match()1735   virtual int min_match() { return body_->min_match(); }
max_match()1736   virtual int max_match() { return body_->max_match(); }
body()1737   RegExpTree* body() { return body_; }
index()1738   int index() { return index_; }
StartRegister(int index)1739   static int StartRegister(int index) { return index * 2; }
EndRegister(int index)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:
RegExpLookahead(RegExpTree * body,bool is_positive,int capture_count,int capture_from)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();
min_match()1765   virtual int min_match() { return 0; }
max_match()1766   virtual int max_match() { return 0; }
body()1767   RegExpTree* body() { return body_; }
is_positive()1768   bool is_positive() { return is_positive_; }
capture_count()1769   int capture_count() { return capture_count_; }
capture_from()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:
RegExpBackReference(RegExpCapture * capture)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();
min_match()1788   virtual int min_match() { return 0; }
max_match()1789   virtual int max_match() { return capture_->max_match(); }
index()1790   int index() { return capture_->index(); }
capture()1791   RegExpCapture* capture() { return capture_; }
1792  private:
1793   RegExpCapture* capture_;
1794 };
1795 
1796 
1797 class RegExpEmpty: public RegExpTree {
1798  public:
RegExpEmpty()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();
min_match()1805   virtual int min_match() { return 0; }
max_match()1806   virtual int max_match() { return 0; }
GetInstance()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:
AstVisitor()1819   AstVisitor() : stack_overflow_(false) { }
~AstVisitor()1820   virtual ~AstVisitor() { }
1821 
1822   // Dispatch
Visit(AstNode * node)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.
HasStackOverflow()1831   bool HasStackOverflow() const { return stack_overflow_; }
CheckStackOverflow()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.
SetStackOverflow()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