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