dad80576bdde36dcd8a22d4740b06960b9f50d50
[profile/ivi/qtjsbackend.git] / src / 3rdparty / v8 / src / ast.h
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #ifndef V8_AST_H_
29 #define V8_AST_H_
30
31 #include "v8.h"
32
33 #include "assembler.h"
34 #include "factory.h"
35 #include "isolate.h"
36 #include "jsregexp.h"
37 #include "list-inl.h"
38 #include "runtime.h"
39 #include "small-pointer-list.h"
40 #include "smart-array-pointer.h"
41 #include "token.h"
42 #include "utils.h"
43 #include "variables.h"
44 #include "interface.h"
45 #include "zone-inl.h"
46
47 namespace v8 {
48 namespace internal {
49
50 // The abstract syntax tree is an intermediate, light-weight
51 // representation of the parsed JavaScript code suitable for
52 // compilation to native code.
53
54 // Nodes are allocated in a separate zone, which allows faster
55 // allocation and constant-time deallocation of the entire syntax
56 // tree.
57
58
59 // ----------------------------------------------------------------------------
60 // Nodes of the abstract syntax tree. Only concrete classes are
61 // enumerated here.
62
63 #define DECLARATION_NODE_LIST(V)                \
64   V(VariableDeclaration)                        \
65   V(FunctionDeclaration)                        \
66   V(ModuleDeclaration)                          \
67   V(ImportDeclaration)                          \
68   V(ExportDeclaration)                          \
69
70 #define MODULE_NODE_LIST(V)                     \
71   V(ModuleLiteral)                              \
72   V(ModuleVariable)                             \
73   V(ModulePath)                                 \
74   V(ModuleUrl)
75
76 #define STATEMENT_NODE_LIST(V)                  \
77   V(Block)                                      \
78   V(ExpressionStatement)                        \
79   V(EmptyStatement)                             \
80   V(IfStatement)                                \
81   V(ContinueStatement)                          \
82   V(BreakStatement)                             \
83   V(ReturnStatement)                            \
84   V(WithStatement)                              \
85   V(SwitchStatement)                            \
86   V(DoWhileStatement)                           \
87   V(WhileStatement)                             \
88   V(ForStatement)                               \
89   V(ForInStatement)                             \
90   V(TryCatchStatement)                          \
91   V(TryFinallyStatement)                        \
92   V(DebuggerStatement)
93
94 #define EXPRESSION_NODE_LIST(V)                 \
95   V(FunctionLiteral)                            \
96   V(SharedFunctionInfoLiteral)                  \
97   V(Conditional)                                \
98   V(VariableProxy)                              \
99   V(Literal)                                    \
100   V(RegExpLiteral)                              \
101   V(ObjectLiteral)                              \
102   V(ArrayLiteral)                               \
103   V(Assignment)                                 \
104   V(Throw)                                      \
105   V(Property)                                   \
106   V(Call)                                       \
107   V(CallNew)                                    \
108   V(CallRuntime)                                \
109   V(UnaryOperation)                             \
110   V(CountOperation)                             \
111   V(BinaryOperation)                            \
112   V(CompareOperation)                           \
113   V(ThisFunction)
114
115 #define AST_NODE_LIST(V)                        \
116   DECLARATION_NODE_LIST(V)                      \
117   MODULE_NODE_LIST(V)                           \
118   STATEMENT_NODE_LIST(V)                        \
119   EXPRESSION_NODE_LIST(V)
120
121 // Forward declarations
122 class AstConstructionVisitor;
123 template<class> class AstNodeFactory;
124 class AstVisitor;
125 class Declaration;
126 class Module;
127 class BreakableStatement;
128 class Expression;
129 class IterationStatement;
130 class MaterializedLiteral;
131 class Statement;
132 class TargetCollector;
133 class TypeFeedbackOracle;
134
135 class RegExpAlternative;
136 class RegExpAssertion;
137 class RegExpAtom;
138 class RegExpBackReference;
139 class RegExpCapture;
140 class RegExpCharacterClass;
141 class RegExpCompiler;
142 class RegExpDisjunction;
143 class RegExpEmpty;
144 class RegExpLookahead;
145 class RegExpQuantifier;
146 class RegExpText;
147
148 #define DEF_FORWARD_DECLARATION(type) class type;
149 AST_NODE_LIST(DEF_FORWARD_DECLARATION)
150 #undef DEF_FORWARD_DECLARATION
151
152
153 // Typedef only introduced to avoid unreadable code.
154 // Please do appreciate the required space in "> >".
155 typedef ZoneList<Handle<String> > ZoneStringList;
156 typedef ZoneList<Handle<Object> > ZoneObjectList;
157
158
159 #define DECLARE_NODE_TYPE(type)                                         \
160   virtual void Accept(AstVisitor* v);                                   \
161   virtual AstNode::Type node_type() const { return AstNode::k##type; }
162
163
164 enum AstPropertiesFlag {
165   kDontInline,
166   kDontOptimize,
167   kDontSelfOptimize,
168   kDontSoftInline
169 };
170
171
172 class AstProperties BASE_EMBEDDED {
173  public:
174   class Flags : public EnumSet<AstPropertiesFlag, int> {};
175
176   AstProperties() : node_count_(0) { }
177
178   Flags* flags() { return &flags_; }
179   int node_count() { return node_count_; }
180   void add_node_count(int count) { node_count_ += count; }
181
182  private:
183   Flags flags_;
184   int node_count_;
185 };
186
187
188 class AstNode: public ZoneObject {
189  public:
190 #define DECLARE_TYPE_ENUM(type) k##type,
191   enum Type {
192     AST_NODE_LIST(DECLARE_TYPE_ENUM)
193     kInvalid = -1
194   };
195 #undef DECLARE_TYPE_ENUM
196
197   static const int kNoNumber = -1;
198   static const int kFunctionEntryId = 2;  // Using 0 could disguise errors.
199   // This AST id identifies the point after the declarations have been
200   // visited. We need it to capture the environment effects of declarations
201   // that emit code (function declarations).
202   static const int kDeclarationsId = 3;
203
204   void* operator new(size_t size, Zone* zone) {
205     return zone->New(static_cast<int>(size));
206   }
207
208   AstNode() { }
209
210   virtual ~AstNode() { }
211
212   virtual void Accept(AstVisitor* v) = 0;
213   virtual Type node_type() const { return kInvalid; }
214
215   // Type testing & conversion functions overridden by concrete subclasses.
216 #define DECLARE_NODE_FUNCTIONS(type)                  \
217   bool Is##type() { return node_type() == AstNode::k##type; }          \
218   type* As##type() { return Is##type() ? reinterpret_cast<type*>(this) : NULL; }
219   AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
220 #undef DECLARE_NODE_FUNCTIONS
221
222   virtual Declaration* AsDeclaration() { return NULL; }
223   virtual Statement* AsStatement() { return NULL; }
224   virtual Expression* AsExpression() { return NULL; }
225   virtual TargetCollector* AsTargetCollector() { return NULL; }
226   virtual BreakableStatement* AsBreakableStatement() { return NULL; }
227   virtual IterationStatement* AsIterationStatement() { return NULL; }
228   virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; }
229
230  protected:
231   static int GetNextId(Isolate* isolate) {
232     return ReserveIdRange(isolate, 1);
233   }
234
235   static int ReserveIdRange(Isolate* isolate, int n) {
236     int tmp = isolate->ast_node_id();
237     isolate->set_ast_node_id(tmp + n);
238     return tmp;
239   }
240
241  private:
242   // Hidden to prevent accidental usage. It would have to load the
243   // current zone from the TLS.
244   void* operator new(size_t size);
245
246   friend class CaseClause;  // Generates AST IDs.
247 };
248
249
250 class Statement: public AstNode {
251  public:
252   Statement() : statement_pos_(RelocInfo::kNoPosition) {}
253
254   virtual Statement* AsStatement()  { return this; }
255
256   bool IsEmpty() { return AsEmptyStatement() != NULL; }
257
258   void set_statement_pos(int statement_pos) { statement_pos_ = statement_pos; }
259   int statement_pos() const { return statement_pos_; }
260
261  private:
262   int statement_pos_;
263 };
264
265
266 class SmallMapList {
267  public:
268   SmallMapList() {}
269   explicit SmallMapList(int capacity) : list_(capacity) {}
270
271   void Reserve(int capacity) { list_.Reserve(capacity); }
272   void Clear() { list_.Clear(); }
273   void Sort() { list_.Sort(); }
274
275   bool is_empty() const { return list_.is_empty(); }
276   int length() const { return list_.length(); }
277
278   void Add(Handle<Map> handle) {
279     list_.Add(handle.location());
280   }
281
282   Handle<Map> at(int i) const {
283     return Handle<Map>(list_.at(i));
284   }
285
286   Handle<Map> first() const { return at(0); }
287   Handle<Map> last() const { return at(length() - 1); }
288
289  private:
290   // The list stores pointers to Map*, that is Map**, so it's GC safe.
291   SmallPointerList<Map*> list_;
292
293   DISALLOW_COPY_AND_ASSIGN(SmallMapList);
294 };
295
296
297 class Expression: public AstNode {
298  public:
299   enum Context {
300     // Not assigned a context yet, or else will not be visited during
301     // code generation.
302     kUninitialized,
303     // Evaluated for its side effects.
304     kEffect,
305     // Evaluated for its value (and side effects).
306     kValue,
307     // Evaluated for control flow (and side effects).
308     kTest
309   };
310
311   virtual int position() const {
312     UNREACHABLE();
313     return 0;
314   }
315
316   virtual Expression* AsExpression()  { return this; }
317
318   virtual bool IsValidLeftHandSide() { return false; }
319
320   // Helpers for ToBoolean conversion.
321   virtual bool ToBooleanIsTrue() { return false; }
322   virtual bool ToBooleanIsFalse() { return false; }
323
324   // Symbols that cannot be parsed as array indices are considered property
325   // names.  We do not treat symbols that can be array indexes as property
326   // names because [] for string objects is handled only by keyed ICs.
327   virtual bool IsPropertyName() { return false; }
328
329   // True iff the result can be safely overwritten (to avoid allocation).
330   // False for operations that can return one of their operands.
331   virtual bool ResultOverwriteAllowed() { return false; }
332
333   // True iff the expression is a literal represented as a smi.
334   bool IsSmiLiteral();
335
336   // True iff the expression is a string literal.
337   bool IsStringLiteral();
338
339   // True iff the expression is the null literal.
340   bool IsNullLiteral();
341
342   // Type feedback information for assignments and properties.
343   virtual bool IsMonomorphic() {
344     UNREACHABLE();
345     return false;
346   }
347   virtual SmallMapList* GetReceiverTypes() {
348     UNREACHABLE();
349     return NULL;
350   }
351   Handle<Map> GetMonomorphicReceiverType() {
352     ASSERT(IsMonomorphic());
353     SmallMapList* types = GetReceiverTypes();
354     ASSERT(types != NULL && types->length() == 1);
355     return types->at(0);
356   }
357
358   unsigned id() const { return id_; }
359   unsigned test_id() const { return test_id_; }
360
361  protected:
362   explicit Expression(Isolate* isolate)
363       : id_(GetNextId(isolate)),
364         test_id_(GetNextId(isolate)) {}
365
366  private:
367   int id_;
368   int test_id_;
369 };
370
371
372 class BreakableStatement: public Statement {
373  public:
374   enum Type {
375     TARGET_FOR_ANONYMOUS,
376     TARGET_FOR_NAMED_ONLY
377   };
378
379   // The labels associated with this statement. May be NULL;
380   // if it is != NULL, guaranteed to contain at least one entry.
381   ZoneStringList* labels() const { return labels_; }
382
383   // Type testing & conversion.
384   virtual BreakableStatement* AsBreakableStatement() { return this; }
385
386   // Code generation
387   Label* break_target() { return &break_target_; }
388
389   // Testers.
390   bool is_target_for_anonymous() const { return type_ == TARGET_FOR_ANONYMOUS; }
391
392   // Bailout support.
393   int EntryId() const { return entry_id_; }
394   int ExitId() const { return exit_id_; }
395
396  protected:
397   BreakableStatement(Isolate* isolate, ZoneStringList* labels, Type type)
398       : labels_(labels),
399         type_(type),
400         entry_id_(GetNextId(isolate)),
401         exit_id_(GetNextId(isolate)) {
402     ASSERT(labels == NULL || labels->length() > 0);
403   }
404
405
406  private:
407   ZoneStringList* labels_;
408   Type type_;
409   Label break_target_;
410   int entry_id_;
411   int exit_id_;
412 };
413
414
415 class Block: public BreakableStatement {
416  public:
417   DECLARE_NODE_TYPE(Block)
418
419   void AddStatement(Statement* statement) { statements_.Add(statement); }
420
421   ZoneList<Statement*>* statements() { return &statements_; }
422   bool is_initializer_block() const { return is_initializer_block_; }
423
424   Scope* scope() const { return scope_; }
425   void set_scope(Scope* scope) { scope_ = scope; }
426
427  protected:
428   template<class> friend class AstNodeFactory;
429
430   Block(Isolate* isolate,
431         ZoneStringList* labels,
432         int capacity,
433         bool is_initializer_block)
434       : BreakableStatement(isolate, labels, TARGET_FOR_NAMED_ONLY),
435         statements_(capacity),
436         is_initializer_block_(is_initializer_block),
437         scope_(NULL) {
438   }
439
440  private:
441   ZoneList<Statement*> statements_;
442   bool is_initializer_block_;
443   Scope* scope_;
444 };
445
446
447 class Declaration: public AstNode {
448  public:
449   VariableProxy* proxy() const { return proxy_; }
450   VariableMode mode() const { return mode_; }
451   Scope* scope() const { return scope_; }
452   virtual InitializationFlag initialization() const = 0;
453   virtual bool IsInlineable() const;
454
455   virtual Declaration* AsDeclaration() { return this; }
456
457  protected:
458   Declaration(VariableProxy* proxy,
459               VariableMode mode,
460               Scope* scope)
461       : proxy_(proxy),
462         mode_(mode),
463         scope_(scope) {
464     ASSERT(mode == VAR ||
465            mode == CONST ||
466            mode == CONST_HARMONY ||
467            mode == LET);
468   }
469
470  private:
471   VariableProxy* proxy_;
472   VariableMode mode_;
473
474   // Nested scope from which the declaration originated.
475   Scope* scope_;
476 };
477
478
479 class VariableDeclaration: public Declaration {
480  public:
481   DECLARE_NODE_TYPE(VariableDeclaration)
482
483   virtual InitializationFlag initialization() const {
484     return mode() == VAR ? kCreatedInitialized : kNeedsInitialization;
485   }
486
487  protected:
488   template<class> friend class AstNodeFactory;
489
490   VariableDeclaration(VariableProxy* proxy,
491                       VariableMode mode,
492                       Scope* scope)
493       : Declaration(proxy, mode, scope) {
494   }
495 };
496
497
498 class FunctionDeclaration: public Declaration {
499  public:
500   DECLARE_NODE_TYPE(FunctionDeclaration)
501
502   FunctionLiteral* fun() const { return fun_; }
503   virtual InitializationFlag initialization() const {
504     return kCreatedInitialized;
505   }
506   virtual bool IsInlineable() const;
507
508  protected:
509   template<class> friend class AstNodeFactory;
510
511   FunctionDeclaration(VariableProxy* proxy,
512                       VariableMode mode,
513                       FunctionLiteral* fun,
514                       Scope* scope)
515       : Declaration(proxy, mode, scope),
516         fun_(fun) {
517     // At the moment there are no "const functions" in JavaScript...
518     ASSERT(mode == VAR || mode == LET);
519     ASSERT(fun != NULL);
520   }
521
522  private:
523   FunctionLiteral* fun_;
524 };
525
526
527 class ModuleDeclaration: public Declaration {
528  public:
529   DECLARE_NODE_TYPE(ModuleDeclaration)
530
531   Module* module() const { return module_; }
532   virtual InitializationFlag initialization() const {
533     return kCreatedInitialized;
534   }
535
536  protected:
537   template<class> friend class AstNodeFactory;
538
539   ModuleDeclaration(VariableProxy* proxy,
540                     Module* module,
541                     Scope* scope)
542       : Declaration(proxy, LET, scope),
543         module_(module) {
544   }
545
546  private:
547   Module* module_;
548 };
549
550
551 class ImportDeclaration: public Declaration {
552  public:
553   DECLARE_NODE_TYPE(ImportDeclaration)
554
555   Module* module() const { return module_; }
556   virtual InitializationFlag initialization() const {
557     return kCreatedInitialized;
558   }
559
560  protected:
561   template<class> friend class AstNodeFactory;
562
563   ImportDeclaration(VariableProxy* proxy,
564                     Module* module,
565                     Scope* scope)
566       : Declaration(proxy, LET, scope),
567         module_(module) {
568   }
569
570  private:
571   Module* module_;
572 };
573
574
575 class ExportDeclaration: public Declaration {
576  public:
577   DECLARE_NODE_TYPE(ExportDeclaration)
578
579   virtual InitializationFlag initialization() const {
580     return kCreatedInitialized;
581   }
582
583  protected:
584   template<class> friend class AstNodeFactory;
585
586   ExportDeclaration(VariableProxy* proxy,
587                     Scope* scope)
588       : Declaration(proxy, LET, scope) {
589   }
590 };
591
592
593 class Module: public AstNode {
594  public:
595   Interface* interface() const { return interface_; }
596
597  protected:
598   Module() : interface_(Interface::NewModule()) {}
599   explicit Module(Interface* interface) : interface_(interface) {}
600
601  private:
602   Interface* interface_;
603 };
604
605
606 class ModuleLiteral: public Module {
607  public:
608   DECLARE_NODE_TYPE(ModuleLiteral)
609
610   Block* body() const { return body_; }
611   Handle<Context> context() const { return context_; }
612
613  protected:
614   template<class> friend class AstNodeFactory;
615
616   ModuleLiteral(Block* body, Interface* interface)
617       : Module(interface),
618         body_(body) {
619   }
620
621  private:
622   Block* body_;
623   Handle<Context> context_;
624 };
625
626
627 class ModuleVariable: public Module {
628  public:
629   DECLARE_NODE_TYPE(ModuleVariable)
630
631   VariableProxy* proxy() const { return proxy_; }
632
633  protected:
634   template<class> friend class AstNodeFactory;
635
636   inline explicit ModuleVariable(VariableProxy* proxy);
637
638  private:
639   VariableProxy* proxy_;
640 };
641
642
643 class ModulePath: public Module {
644  public:
645   DECLARE_NODE_TYPE(ModulePath)
646
647   Module* module() const { return module_; }
648   Handle<String> name() const { return name_; }
649
650  protected:
651   template<class> friend class AstNodeFactory;
652
653   ModulePath(Module* module, Handle<String> name)
654       : module_(module),
655         name_(name) {
656   }
657
658  private:
659   Module* module_;
660   Handle<String> name_;
661 };
662
663
664 class ModuleUrl: public Module {
665  public:
666   DECLARE_NODE_TYPE(ModuleUrl)
667
668   Handle<String> url() const { return url_; }
669
670  protected:
671   template<class> friend class AstNodeFactory;
672
673   explicit ModuleUrl(Handle<String> url) : url_(url) {
674   }
675
676  private:
677   Handle<String> url_;
678 };
679
680
681 class IterationStatement: public BreakableStatement {
682  public:
683   // Type testing & conversion.
684   virtual IterationStatement* AsIterationStatement() { return this; }
685
686   Statement* body() const { return body_; }
687
688   // Bailout support.
689   int OsrEntryId() const { return osr_entry_id_; }
690   virtual int ContinueId() const = 0;
691   virtual int StackCheckId() const = 0;
692
693   // Code generation
694   Label* continue_target()  { return &continue_target_; }
695
696  protected:
697   IterationStatement(Isolate* isolate, ZoneStringList* labels)
698       : BreakableStatement(isolate, labels, TARGET_FOR_ANONYMOUS),
699         body_(NULL),
700         osr_entry_id_(GetNextId(isolate)) {
701   }
702
703   void Initialize(Statement* body) {
704     body_ = body;
705   }
706
707  private:
708   Statement* body_;
709   Label continue_target_;
710   int osr_entry_id_;
711 };
712
713
714 class DoWhileStatement: public IterationStatement {
715  public:
716   DECLARE_NODE_TYPE(DoWhileStatement)
717
718   void Initialize(Expression* cond, Statement* body) {
719     IterationStatement::Initialize(body);
720     cond_ = cond;
721   }
722
723   Expression* cond() const { return cond_; }
724
725   // Position where condition expression starts. We need it to make
726   // the loop's condition a breakable location.
727   int condition_position() { return condition_position_; }
728   void set_condition_position(int pos) { condition_position_ = pos; }
729
730   // Bailout support.
731   virtual int ContinueId() const { return continue_id_; }
732   virtual int StackCheckId() const { return back_edge_id_; }
733   int BackEdgeId() const { return back_edge_id_; }
734
735  protected:
736   template<class> friend class AstNodeFactory;
737
738   DoWhileStatement(Isolate* isolate, ZoneStringList* labels)
739       : IterationStatement(isolate, labels),
740         cond_(NULL),
741         condition_position_(-1),
742         continue_id_(GetNextId(isolate)),
743         back_edge_id_(GetNextId(isolate)) {
744   }
745
746  private:
747   Expression* cond_;
748   int condition_position_;
749   int continue_id_;
750   int back_edge_id_;
751 };
752
753
754 class WhileStatement: public IterationStatement {
755  public:
756   DECLARE_NODE_TYPE(WhileStatement)
757
758   void Initialize(Expression* cond, Statement* body) {
759     IterationStatement::Initialize(body);
760     cond_ = cond;
761   }
762
763   Expression* cond() const { return cond_; }
764   bool may_have_function_literal() const {
765     return may_have_function_literal_;
766   }
767   void set_may_have_function_literal(bool value) {
768     may_have_function_literal_ = value;
769   }
770
771   // Bailout support.
772   virtual int ContinueId() const { return EntryId(); }
773   virtual int StackCheckId() const { return body_id_; }
774   int BodyId() const { return body_id_; }
775
776  protected:
777   template<class> friend class AstNodeFactory;
778
779   WhileStatement(Isolate* isolate, ZoneStringList* labels)
780       : IterationStatement(isolate, labels),
781         cond_(NULL),
782         may_have_function_literal_(true),
783         body_id_(GetNextId(isolate)) {
784   }
785
786  private:
787   Expression* cond_;
788   // True if there is a function literal subexpression in the condition.
789   bool may_have_function_literal_;
790   int body_id_;
791 };
792
793
794 class ForStatement: public IterationStatement {
795  public:
796   DECLARE_NODE_TYPE(ForStatement)
797
798   void Initialize(Statement* init,
799                   Expression* cond,
800                   Statement* next,
801                   Statement* body) {
802     IterationStatement::Initialize(body);
803     init_ = init;
804     cond_ = cond;
805     next_ = next;
806   }
807
808   Statement* init() const { return init_; }
809   Expression* cond() const { return cond_; }
810   Statement* next() const { return next_; }
811
812   bool may_have_function_literal() const {
813     return may_have_function_literal_;
814   }
815   void set_may_have_function_literal(bool value) {
816     may_have_function_literal_ = value;
817   }
818
819   // Bailout support.
820   virtual int ContinueId() const { return continue_id_; }
821   virtual int StackCheckId() const { return body_id_; }
822   int BodyId() const { return body_id_; }
823
824   bool is_fast_smi_loop() { return loop_variable_ != NULL; }
825   Variable* loop_variable() { return loop_variable_; }
826   void set_loop_variable(Variable* var) { loop_variable_ = var; }
827
828  protected:
829   template<class> friend class AstNodeFactory;
830
831   ForStatement(Isolate* isolate, ZoneStringList* labels)
832       : IterationStatement(isolate, labels),
833         init_(NULL),
834         cond_(NULL),
835         next_(NULL),
836         may_have_function_literal_(true),
837         loop_variable_(NULL),
838         continue_id_(GetNextId(isolate)),
839         body_id_(GetNextId(isolate)) {
840   }
841
842  private:
843   Statement* init_;
844   Expression* cond_;
845   Statement* next_;
846   // True if there is a function literal subexpression in the condition.
847   bool may_have_function_literal_;
848   Variable* loop_variable_;
849   int continue_id_;
850   int body_id_;
851 };
852
853
854 class ForInStatement: public IterationStatement {
855  public:
856   DECLARE_NODE_TYPE(ForInStatement)
857
858   void Initialize(Expression* each, Expression* enumerable, Statement* body) {
859     IterationStatement::Initialize(body);
860     each_ = each;
861     enumerable_ = enumerable;
862   }
863
864   Expression* each() const { return each_; }
865   Expression* enumerable() const { return enumerable_; }
866
867   virtual int ContinueId() const { return EntryId(); }
868   virtual int StackCheckId() const { return body_id_; }
869   int BodyId() const { return body_id_; }
870   int PrepareId() const { return prepare_id_; }
871
872  protected:
873   template<class> friend class AstNodeFactory;
874
875   ForInStatement(Isolate* isolate, ZoneStringList* labels)
876       : IterationStatement(isolate, labels),
877         each_(NULL),
878         enumerable_(NULL),
879         body_id_(GetNextId(isolate)),
880         prepare_id_(GetNextId(isolate)) {
881   }
882
883  private:
884   Expression* each_;
885   Expression* enumerable_;
886   int body_id_;
887   int prepare_id_;
888 };
889
890
891 class ExpressionStatement: public Statement {
892  public:
893   DECLARE_NODE_TYPE(ExpressionStatement)
894
895   void set_expression(Expression* e) { expression_ = e; }
896   Expression* expression() const { return expression_; }
897
898  protected:
899   template<class> friend class AstNodeFactory;
900
901   explicit ExpressionStatement(Expression* expression)
902       : expression_(expression) { }
903
904  private:
905   Expression* expression_;
906 };
907
908
909 class ContinueStatement: public Statement {
910  public:
911   DECLARE_NODE_TYPE(ContinueStatement)
912
913   IterationStatement* target() const { return target_; }
914
915  protected:
916   template<class> friend class AstNodeFactory;
917
918   explicit ContinueStatement(IterationStatement* target)
919       : target_(target) { }
920
921  private:
922   IterationStatement* target_;
923 };
924
925
926 class BreakStatement: public Statement {
927  public:
928   DECLARE_NODE_TYPE(BreakStatement)
929
930   BreakableStatement* target() const { return target_; }
931
932  protected:
933   template<class> friend class AstNodeFactory;
934
935   explicit BreakStatement(BreakableStatement* target)
936       : target_(target) { }
937
938  private:
939   BreakableStatement* target_;
940 };
941
942
943 class ReturnStatement: public Statement {
944  public:
945   DECLARE_NODE_TYPE(ReturnStatement)
946
947   Expression* expression() const { return expression_; }
948
949  protected:
950   template<class> friend class AstNodeFactory;
951
952   explicit ReturnStatement(Expression* expression)
953       : expression_(expression) { }
954
955  private:
956   Expression* expression_;
957 };
958
959
960 class WithStatement: public Statement {
961  public:
962   DECLARE_NODE_TYPE(WithStatement)
963
964   Expression* expression() const { return expression_; }
965   Statement* statement() const { return statement_; }
966
967  protected:
968   template<class> friend class AstNodeFactory;
969
970   WithStatement(Expression* expression, Statement* statement)
971       : expression_(expression),
972         statement_(statement) { }
973
974  private:
975   Expression* expression_;
976   Statement* statement_;
977 };
978
979
980 class CaseClause: public ZoneObject {
981  public:
982   CaseClause(Isolate* isolate,
983              Expression* label,
984              ZoneList<Statement*>* statements,
985              int pos);
986
987   bool is_default() const { return label_ == NULL; }
988   Expression* label() const {
989     CHECK(!is_default());
990     return label_;
991   }
992   Label* body_target() { return &body_target_; }
993   ZoneList<Statement*>* statements() const { return statements_; }
994
995   int position() const { return position_; }
996   void set_position(int pos) { position_ = pos; }
997
998   int EntryId() { return entry_id_; }
999   int CompareId() { return compare_id_; }
1000
1001   // Type feedback information.
1002   void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1003   bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
1004   bool IsSymbolCompare() { return compare_type_ == SYMBOL_ONLY; }
1005   bool IsStringCompare() { return compare_type_ == STRING_ONLY; }
1006   bool IsObjectCompare() { return compare_type_ == OBJECT_ONLY; }
1007
1008  private:
1009   Expression* label_;
1010   Label body_target_;
1011   ZoneList<Statement*>* statements_;
1012   int position_;
1013   enum CompareTypeFeedback {
1014     NONE,
1015     SMI_ONLY,
1016     SYMBOL_ONLY,
1017     STRING_ONLY,
1018     OBJECT_ONLY
1019   };
1020   CompareTypeFeedback compare_type_;
1021   int compare_id_;
1022   int entry_id_;
1023 };
1024
1025
1026 class SwitchStatement: public BreakableStatement {
1027  public:
1028   DECLARE_NODE_TYPE(SwitchStatement)
1029
1030   void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) {
1031     tag_ = tag;
1032     cases_ = cases;
1033   }
1034
1035   Expression* tag() const { return tag_; }
1036   ZoneList<CaseClause*>* cases() const { return cases_; }
1037
1038  protected:
1039   template<class> friend class AstNodeFactory;
1040
1041   SwitchStatement(Isolate* isolate, ZoneStringList* labels)
1042       : BreakableStatement(isolate, labels, TARGET_FOR_ANONYMOUS),
1043         tag_(NULL),
1044         cases_(NULL) { }
1045
1046  private:
1047   Expression* tag_;
1048   ZoneList<CaseClause*>* cases_;
1049 };
1050
1051
1052 // If-statements always have non-null references to their then- and
1053 // else-parts. When parsing if-statements with no explicit else-part,
1054 // the parser implicitly creates an empty statement. Use the
1055 // HasThenStatement() and HasElseStatement() functions to check if a
1056 // given if-statement has a then- or an else-part containing code.
1057 class IfStatement: public Statement {
1058  public:
1059   DECLARE_NODE_TYPE(IfStatement)
1060
1061   bool HasThenStatement() const { return !then_statement()->IsEmpty(); }
1062   bool HasElseStatement() const { return !else_statement()->IsEmpty(); }
1063
1064   Expression* condition() const { return condition_; }
1065   Statement* then_statement() const { return then_statement_; }
1066   Statement* else_statement() const { return else_statement_; }
1067
1068   int IfId() const { return if_id_; }
1069   int ThenId() const { return then_id_; }
1070   int ElseId() const { return else_id_; }
1071
1072  protected:
1073   template<class> friend class AstNodeFactory;
1074
1075   IfStatement(Isolate* isolate,
1076               Expression* condition,
1077               Statement* then_statement,
1078               Statement* else_statement)
1079       : condition_(condition),
1080         then_statement_(then_statement),
1081         else_statement_(else_statement),
1082         if_id_(GetNextId(isolate)),
1083         then_id_(GetNextId(isolate)),
1084         else_id_(GetNextId(isolate)) {
1085   }
1086
1087  private:
1088   Expression* condition_;
1089   Statement* then_statement_;
1090   Statement* else_statement_;
1091   int if_id_;
1092   int then_id_;
1093   int else_id_;
1094 };
1095
1096
1097 // NOTE: TargetCollectors are represented as nodes to fit in the target
1098 // stack in the compiler; this should probably be reworked.
1099 class TargetCollector: public AstNode {
1100  public:
1101   TargetCollector() : targets_(0) { }
1102
1103   // Adds a jump target to the collector. The collector stores a pointer not
1104   // a copy of the target to make binding work, so make sure not to pass in
1105   // references to something on the stack.
1106   void AddTarget(Label* target);
1107
1108   // Virtual behaviour. TargetCollectors are never part of the AST.
1109   virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
1110   virtual TargetCollector* AsTargetCollector() { return this; }
1111
1112   ZoneList<Label*>* targets() { return &targets_; }
1113
1114  private:
1115   ZoneList<Label*> targets_;
1116 };
1117
1118
1119 class TryStatement: public Statement {
1120  public:
1121   void set_escaping_targets(ZoneList<Label*>* targets) {
1122     escaping_targets_ = targets;
1123   }
1124
1125   int index() const { return index_; }
1126   Block* try_block() const { return try_block_; }
1127   ZoneList<Label*>* escaping_targets() const { return escaping_targets_; }
1128
1129  protected:
1130   TryStatement(int index, Block* try_block)
1131       : index_(index),
1132         try_block_(try_block),
1133         escaping_targets_(NULL) { }
1134
1135  private:
1136   // Unique (per-function) index of this handler.  This is not an AST ID.
1137   int index_;
1138
1139   Block* try_block_;
1140   ZoneList<Label*>* escaping_targets_;
1141 };
1142
1143
1144 class TryCatchStatement: public TryStatement {
1145  public:
1146   DECLARE_NODE_TYPE(TryCatchStatement)
1147
1148   Scope* scope() { return scope_; }
1149   Variable* variable() { return variable_; }
1150   Block* catch_block() const { return catch_block_; }
1151
1152  protected:
1153   template<class> friend class AstNodeFactory;
1154
1155   TryCatchStatement(int index,
1156                     Block* try_block,
1157                     Scope* scope,
1158                     Variable* variable,
1159                     Block* catch_block)
1160       : TryStatement(index, try_block),
1161         scope_(scope),
1162         variable_(variable),
1163         catch_block_(catch_block) {
1164   }
1165
1166  private:
1167   Scope* scope_;
1168   Variable* variable_;
1169   Block* catch_block_;
1170 };
1171
1172
1173 class TryFinallyStatement: public TryStatement {
1174  public:
1175   DECLARE_NODE_TYPE(TryFinallyStatement)
1176
1177   Block* finally_block() const { return finally_block_; }
1178
1179  protected:
1180   template<class> friend class AstNodeFactory;
1181
1182   TryFinallyStatement(int index, Block* try_block, Block* finally_block)
1183       : TryStatement(index, try_block),
1184         finally_block_(finally_block) { }
1185
1186  private:
1187   Block* finally_block_;
1188 };
1189
1190
1191 class DebuggerStatement: public Statement {
1192  public:
1193   DECLARE_NODE_TYPE(DebuggerStatement)
1194
1195  protected:
1196   template<class> friend class AstNodeFactory;
1197
1198   DebuggerStatement() {}
1199 };
1200
1201
1202 class EmptyStatement: public Statement {
1203  public:
1204   DECLARE_NODE_TYPE(EmptyStatement)
1205
1206  protected:
1207   template<class> friend class AstNodeFactory;
1208
1209   EmptyStatement() {}
1210 };
1211
1212
1213 class Literal: public Expression {
1214  public:
1215   DECLARE_NODE_TYPE(Literal)
1216
1217   virtual bool IsPropertyName() {
1218     if (handle_->IsSymbol()) {
1219       uint32_t ignored;
1220       return !String::cast(*handle_)->AsArrayIndex(&ignored);
1221     }
1222     return false;
1223   }
1224
1225   Handle<String> AsPropertyName() {
1226     ASSERT(IsPropertyName());
1227     return Handle<String>::cast(handle_);
1228   }
1229
1230   virtual bool ToBooleanIsTrue() { return handle_->ToBoolean()->IsTrue(); }
1231   virtual bool ToBooleanIsFalse() { return handle_->ToBoolean()->IsFalse(); }
1232
1233   // Identity testers.
1234   bool IsNull() const {
1235     ASSERT(!handle_.is_null());
1236     return handle_->IsNull();
1237   }
1238   bool IsTrue() const {
1239     ASSERT(!handle_.is_null());
1240     return handle_->IsTrue();
1241   }
1242   bool IsFalse() const {
1243     ASSERT(!handle_.is_null());
1244     return handle_->IsFalse();
1245   }
1246
1247   Handle<Object> handle() const { return handle_; }
1248
1249   // Support for using Literal as a HashMap key. NOTE: Currently, this works
1250   // only for string and number literals!
1251   uint32_t Hash() { return ToString()->Hash(); }
1252
1253   static bool Match(void* literal1, void* literal2) {
1254     Handle<String> s1 = static_cast<Literal*>(literal1)->ToString();
1255     Handle<String> s2 = static_cast<Literal*>(literal2)->ToString();
1256     return s1->Equals(*s2);
1257   }
1258
1259  protected:
1260   template<class> friend class AstNodeFactory;
1261
1262   Literal(Isolate* isolate, Handle<Object> handle)
1263       : Expression(isolate),
1264         handle_(handle) { }
1265
1266  private:
1267   Handle<String> ToString();
1268
1269   Handle<Object> handle_;
1270 };
1271
1272
1273 // Base class for literals that needs space in the corresponding JSFunction.
1274 class MaterializedLiteral: public Expression {
1275  public:
1276   virtual MaterializedLiteral* AsMaterializedLiteral() { return this; }
1277
1278   int literal_index() { return literal_index_; }
1279
1280   // A materialized literal is simple if the values consist of only
1281   // constants and simple object and array literals.
1282   bool is_simple() const { return is_simple_; }
1283
1284   int depth() const { return depth_; }
1285
1286  protected:
1287   MaterializedLiteral(Isolate* isolate,
1288                       int literal_index,
1289                       bool is_simple,
1290                       int depth)
1291       : Expression(isolate),
1292         literal_index_(literal_index),
1293         is_simple_(is_simple),
1294         depth_(depth) {}
1295
1296  private:
1297   int literal_index_;
1298   bool is_simple_;
1299   int depth_;
1300 };
1301
1302
1303 // An object literal has a boilerplate object that is used
1304 // for minimizing the work when constructing it at runtime.
1305 class ObjectLiteral: public MaterializedLiteral {
1306  public:
1307   // Property is used for passing information
1308   // about an object literal's properties from the parser
1309   // to the code generator.
1310   class Property: public ZoneObject {
1311    public:
1312     enum Kind {
1313       CONSTANT,              // Property with constant value (compile time).
1314       COMPUTED,              // Property with computed value (execution time).
1315       MATERIALIZED_LITERAL,  // Property value is a materialized literal.
1316       GETTER, SETTER,        // Property is an accessor function.
1317       PROTOTYPE              // Property is __proto__.
1318     };
1319
1320     Property(Literal* key, Expression* value, Isolate* isolate);
1321
1322     Literal* key() { return key_; }
1323     Expression* value() { return value_; }
1324     Kind kind() { return kind_; }
1325
1326     // Type feedback information.
1327     void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1328     bool IsMonomorphic() { return !receiver_type_.is_null(); }
1329     Handle<Map> GetReceiverType() { return receiver_type_; }
1330
1331     bool IsCompileTimeValue();
1332
1333     void set_emit_store(bool emit_store);
1334     bool emit_store();
1335
1336    protected:
1337     template<class> friend class AstNodeFactory;
1338
1339     Property(bool is_getter, FunctionLiteral* value);
1340     void set_key(Literal* key) { key_ = key; }
1341
1342    private:
1343     Literal* key_;
1344     Expression* value_;
1345     Kind kind_;
1346     bool emit_store_;
1347     Handle<Map> receiver_type_;
1348   };
1349
1350   DECLARE_NODE_TYPE(ObjectLiteral)
1351
1352   Handle<FixedArray> constant_properties() const {
1353     return constant_properties_;
1354   }
1355   ZoneList<Property*>* properties() const { return properties_; }
1356
1357   bool fast_elements() const { return fast_elements_; }
1358
1359   bool has_function() { return has_function_; }
1360
1361   // Mark all computed expressions that are bound to a key that
1362   // is shadowed by a later occurrence of the same key. For the
1363   // marked expressions, no store code is emitted.
1364   void CalculateEmitStore();
1365
1366   enum Flags {
1367     kNoFlags = 0,
1368     kFastElements = 1,
1369     kHasFunction = 1 << 1
1370   };
1371
1372   struct Accessors: public ZoneObject {
1373     Accessors() : getter(NULL), setter(NULL) { }
1374     Expression* getter;
1375     Expression* setter;
1376   };
1377
1378  protected:
1379   template<class> friend class AstNodeFactory;
1380
1381   ObjectLiteral(Isolate* isolate,
1382                 Handle<FixedArray> constant_properties,
1383                 ZoneList<Property*>* properties,
1384                 int literal_index,
1385                 bool is_simple,
1386                 bool fast_elements,
1387                 int depth,
1388                 bool has_function)
1389       : MaterializedLiteral(isolate, literal_index, is_simple, depth),
1390         constant_properties_(constant_properties),
1391         properties_(properties),
1392         fast_elements_(fast_elements),
1393         has_function_(has_function) {}
1394
1395  private:
1396   Handle<FixedArray> constant_properties_;
1397   ZoneList<Property*>* properties_;
1398   bool fast_elements_;
1399   bool has_function_;
1400 };
1401
1402
1403 // Node for capturing a regexp literal.
1404 class RegExpLiteral: public MaterializedLiteral {
1405  public:
1406   DECLARE_NODE_TYPE(RegExpLiteral)
1407
1408   Handle<String> pattern() const { return pattern_; }
1409   Handle<String> flags() const { return flags_; }
1410
1411  protected:
1412   template<class> friend class AstNodeFactory;
1413
1414   RegExpLiteral(Isolate* isolate,
1415                 Handle<String> pattern,
1416                 Handle<String> flags,
1417                 int literal_index)
1418       : MaterializedLiteral(isolate, literal_index, false, 1),
1419         pattern_(pattern),
1420         flags_(flags) {}
1421
1422  private:
1423   Handle<String> pattern_;
1424   Handle<String> flags_;
1425 };
1426
1427 // An array literal has a literals object that is used
1428 // for minimizing the work when constructing it at runtime.
1429 class ArrayLiteral: public MaterializedLiteral {
1430  public:
1431   DECLARE_NODE_TYPE(ArrayLiteral)
1432
1433   Handle<FixedArray> constant_elements() const { return constant_elements_; }
1434   ZoneList<Expression*>* values() const { return values_; }
1435
1436   // Return an AST id for an element that is used in simulate instructions.
1437   int GetIdForElement(int i) { return first_element_id_ + i; }
1438
1439  protected:
1440   template<class> friend class AstNodeFactory;
1441
1442   ArrayLiteral(Isolate* isolate,
1443                Handle<FixedArray> constant_elements,
1444                ZoneList<Expression*>* values,
1445                int literal_index,
1446                bool is_simple,
1447                int depth)
1448       : MaterializedLiteral(isolate, literal_index, is_simple, depth),
1449         constant_elements_(constant_elements),
1450         values_(values),
1451         first_element_id_(ReserveIdRange(isolate, values->length())) {}
1452
1453  private:
1454   Handle<FixedArray> constant_elements_;
1455   ZoneList<Expression*>* values_;
1456   int first_element_id_;
1457 };
1458
1459
1460 class VariableProxy: public Expression {
1461  public:
1462   DECLARE_NODE_TYPE(VariableProxy)
1463
1464   virtual bool IsValidLeftHandSide() {
1465     return var_ == NULL ? true : var_->IsValidLeftHandSide();
1466   }
1467
1468   bool IsVariable(Handle<String> n) {
1469     return !is_this() && name().is_identical_to(n);
1470   }
1471
1472   bool IsArguments() { return var_ != NULL && var_->is_arguments(); }
1473
1474   bool IsLValue() {
1475     return is_lvalue_;
1476   }
1477
1478   Handle<String> name() const { return name_; }
1479   Variable* var() const { return var_; }
1480   bool is_this() const { return is_this_; }
1481   int position() const { return position_; }
1482   Interface* interface() const { return interface_; }
1483
1484
1485   void MarkAsTrivial() { is_trivial_ = true; }
1486   void MarkAsLValue() { is_lvalue_ = true; }
1487
1488   // Bind this proxy to the variable var.
1489   void BindTo(Variable* var);
1490
1491  protected:
1492   template<class> friend class AstNodeFactory;
1493
1494   VariableProxy(Isolate* isolate, Variable* var);
1495
1496   VariableProxy(Isolate* isolate,
1497                 Handle<String> name,
1498                 bool is_this,
1499                 int position,
1500                 Interface* interface);
1501
1502   Handle<String> name_;
1503   Variable* var_;  // resolved variable, or NULL
1504   bool is_this_;
1505   bool is_trivial_;
1506   // True if this variable proxy is being used in an assignment
1507   // or with a increment/decrement operator.
1508   bool is_lvalue_;
1509   int position_;
1510   Interface* interface_;
1511 };
1512
1513
1514 class Property: public Expression {
1515  public:
1516   DECLARE_NODE_TYPE(Property)
1517
1518   virtual bool IsValidLeftHandSide() { return true; }
1519
1520   Expression* obj() const { return obj_; }
1521   Expression* key() const { return key_; }
1522   virtual int position() const { return pos_; }
1523
1524   bool IsStringLength() const { return is_string_length_; }
1525   bool IsStringAccess() const { return is_string_access_; }
1526   bool IsFunctionPrototype() const { return is_function_prototype_; }
1527
1528   // Type feedback information.
1529   void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1530   virtual bool IsMonomorphic() { return is_monomorphic_; }
1531   virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
1532   bool IsArrayLength() { return is_array_length_; }
1533   bool IsUninitialized() { return is_uninitialized_; }
1534
1535  protected:
1536   template<class> friend class AstNodeFactory;
1537
1538   Property(Isolate* isolate,
1539            Expression* obj,
1540            Expression* key,
1541            int pos)
1542       : Expression(isolate),
1543         obj_(obj),
1544         key_(key),
1545         pos_(pos),
1546         is_monomorphic_(false),
1547         is_uninitialized_(false),
1548         is_array_length_(false),
1549         is_string_length_(false),
1550         is_string_access_(false),
1551         is_function_prototype_(false) { }
1552
1553  private:
1554   Expression* obj_;
1555   Expression* key_;
1556   int pos_;
1557
1558   SmallMapList receiver_types_;
1559   bool is_monomorphic_ : 1;
1560   bool is_uninitialized_ : 1;
1561   bool is_array_length_ : 1;
1562   bool is_string_length_ : 1;
1563   bool is_string_access_ : 1;
1564   bool is_function_prototype_ : 1;
1565 };
1566
1567
1568 class Call: public Expression {
1569  public:
1570   DECLARE_NODE_TYPE(Call)
1571
1572   Expression* expression() const { return expression_; }
1573   ZoneList<Expression*>* arguments() const { return arguments_; }
1574   virtual int position() const { return pos_; }
1575
1576   void RecordTypeFeedback(TypeFeedbackOracle* oracle,
1577                           CallKind call_kind);
1578   virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
1579   virtual bool IsMonomorphic() { return is_monomorphic_; }
1580   CheckType check_type() const { return check_type_; }
1581   Handle<JSFunction> target() { return target_; }
1582   Handle<JSObject> holder() { return holder_; }
1583   Handle<JSGlobalPropertyCell> cell() { return cell_; }
1584
1585   bool ComputeTarget(Handle<Map> type, Handle<String> name);
1586   bool ComputeGlobalTarget(Handle<GlobalObject> global, LookupResult* lookup);
1587
1588   // Bailout support.
1589   int ReturnId() const { return return_id_; }
1590
1591 #ifdef DEBUG
1592   // Used to assert that the FullCodeGenerator records the return site.
1593   bool return_is_recorded_;
1594 #endif
1595
1596  protected:
1597   template<class> friend class AstNodeFactory;
1598
1599   Call(Isolate* isolate,
1600        Expression* expression,
1601        ZoneList<Expression*>* arguments,
1602        int pos)
1603       : Expression(isolate),
1604         expression_(expression),
1605         arguments_(arguments),
1606         pos_(pos),
1607         is_monomorphic_(false),
1608         check_type_(RECEIVER_MAP_CHECK),
1609         return_id_(GetNextId(isolate)) { }
1610
1611  private:
1612   Expression* expression_;
1613   ZoneList<Expression*>* arguments_;
1614   int pos_;
1615
1616   bool is_monomorphic_;
1617   CheckType check_type_;
1618   SmallMapList receiver_types_;
1619   Handle<JSFunction> target_;
1620   Handle<JSObject> holder_;
1621   Handle<JSGlobalPropertyCell> cell_;
1622
1623   int return_id_;
1624 };
1625
1626
1627 class CallNew: public Expression {
1628  public:
1629   DECLARE_NODE_TYPE(CallNew)
1630
1631   Expression* expression() const { return expression_; }
1632   ZoneList<Expression*>* arguments() const { return arguments_; }
1633   virtual int position() const { return pos_; }
1634
1635   void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1636   virtual bool IsMonomorphic() { return is_monomorphic_; }
1637   Handle<JSFunction> target() { return target_; }
1638
1639   // Bailout support.
1640   int ReturnId() const { return return_id_; }
1641
1642  protected:
1643   template<class> friend class AstNodeFactory;
1644
1645   CallNew(Isolate* isolate,
1646           Expression* expression,
1647           ZoneList<Expression*>* arguments,
1648           int pos)
1649       : Expression(isolate),
1650         expression_(expression),
1651         arguments_(arguments),
1652         pos_(pos),
1653         is_monomorphic_(false),
1654         return_id_(GetNextId(isolate)) { }
1655
1656  private:
1657   Expression* expression_;
1658   ZoneList<Expression*>* arguments_;
1659   int pos_;
1660
1661   bool is_monomorphic_;
1662   Handle<JSFunction> target_;
1663
1664   int return_id_;
1665 };
1666
1667
1668 // The CallRuntime class does not represent any official JavaScript
1669 // language construct. Instead it is used to call a C or JS function
1670 // with a set of arguments. This is used from the builtins that are
1671 // implemented in JavaScript (see "v8natives.js").
1672 class CallRuntime: public Expression {
1673  public:
1674   DECLARE_NODE_TYPE(CallRuntime)
1675
1676   Handle<String> name() const { return name_; }
1677   const Runtime::Function* function() const { return function_; }
1678   ZoneList<Expression*>* arguments() const { return arguments_; }
1679   bool is_jsruntime() const { return function_ == NULL; }
1680
1681  protected:
1682   template<class> friend class AstNodeFactory;
1683
1684   CallRuntime(Isolate* isolate,
1685               Handle<String> name,
1686               const Runtime::Function* function,
1687               ZoneList<Expression*>* arguments)
1688       : Expression(isolate),
1689         name_(name),
1690         function_(function),
1691         arguments_(arguments) { }
1692
1693  private:
1694   Handle<String> name_;
1695   const Runtime::Function* function_;
1696   ZoneList<Expression*>* arguments_;
1697 };
1698
1699
1700 class UnaryOperation: public Expression {
1701  public:
1702   DECLARE_NODE_TYPE(UnaryOperation)
1703
1704   virtual bool ResultOverwriteAllowed();
1705
1706   Token::Value op() const { return op_; }
1707   Expression* expression() const { return expression_; }
1708   virtual int position() const { return pos_; }
1709
1710   int MaterializeTrueId() { return materialize_true_id_; }
1711   int MaterializeFalseId() { return materialize_false_id_; }
1712
1713  protected:
1714   template<class> friend class AstNodeFactory;
1715
1716   UnaryOperation(Isolate* isolate,
1717                  Token::Value op,
1718                  Expression* expression,
1719                  int pos)
1720       : Expression(isolate),
1721         op_(op),
1722         expression_(expression),
1723         pos_(pos),
1724         materialize_true_id_(AstNode::kNoNumber),
1725         materialize_false_id_(AstNode::kNoNumber) {
1726     ASSERT(Token::IsUnaryOp(op));
1727     if (op == Token::NOT) {
1728       materialize_true_id_ = GetNextId(isolate);
1729       materialize_false_id_ = GetNextId(isolate);
1730     }
1731   }
1732
1733  private:
1734   Token::Value op_;
1735   Expression* expression_;
1736   int pos_;
1737
1738   // For unary not (Token::NOT), the AST ids where true and false will
1739   // actually be materialized, respectively.
1740   int materialize_true_id_;
1741   int materialize_false_id_;
1742 };
1743
1744
1745 class BinaryOperation: public Expression {
1746  public:
1747   DECLARE_NODE_TYPE(BinaryOperation)
1748
1749   virtual bool ResultOverwriteAllowed();
1750
1751   Token::Value op() const { return op_; }
1752   Expression* left() const { return left_; }
1753   Expression* right() const { return right_; }
1754   virtual int position() const { return pos_; }
1755
1756   // Bailout support.
1757   int RightId() const { return right_id_; }
1758
1759  protected:
1760   template<class> friend class AstNodeFactory;
1761
1762   BinaryOperation(Isolate* isolate,
1763                   Token::Value op,
1764                   Expression* left,
1765                   Expression* right,
1766                   int pos)
1767       : Expression(isolate), op_(op), left_(left), right_(right), pos_(pos) {
1768     ASSERT(Token::IsBinaryOp(op));
1769     right_id_ = (op == Token::AND || op == Token::OR)
1770         ? GetNextId(isolate)
1771         : AstNode::kNoNumber;
1772   }
1773
1774  private:
1775   Token::Value op_;
1776   Expression* left_;
1777   Expression* right_;
1778   int pos_;
1779   // The short-circuit logical operations have an AST ID for their
1780   // right-hand subexpression.
1781   int right_id_;
1782 };
1783
1784
1785 class CountOperation: public Expression {
1786  public:
1787   DECLARE_NODE_TYPE(CountOperation)
1788
1789   bool is_prefix() const { return is_prefix_; }
1790   bool is_postfix() const { return !is_prefix_; }
1791
1792   Token::Value op() const { return op_; }
1793   Token::Value binary_op() {
1794     return (op() == Token::INC) ? Token::ADD : Token::SUB;
1795   }
1796
1797   Expression* expression() const { return expression_; }
1798   virtual int position() const { return pos_; }
1799
1800   virtual void MarkAsStatement() { is_prefix_ = true; }
1801
1802   void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1803   virtual bool IsMonomorphic() { return is_monomorphic_; }
1804   virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
1805
1806   // Bailout support.
1807   int AssignmentId() const { return assignment_id_; }
1808   int CountId() const { return count_id_; }
1809
1810  protected:
1811   template<class> friend class AstNodeFactory;
1812
1813   CountOperation(Isolate* isolate,
1814                  Token::Value op,
1815                  bool is_prefix,
1816                  Expression* expr,
1817                  int pos)
1818       : Expression(isolate),
1819         op_(op),
1820         is_prefix_(is_prefix),
1821         expression_(expr),
1822         pos_(pos),
1823         assignment_id_(GetNextId(isolate)),
1824         count_id_(GetNextId(isolate)) {}
1825
1826  private:
1827   Token::Value op_;
1828   bool is_prefix_;
1829   bool is_monomorphic_;
1830   Expression* expression_;
1831   int pos_;
1832   int assignment_id_;
1833   int count_id_;
1834   SmallMapList receiver_types_;
1835 };
1836
1837
1838 class CompareOperation: public Expression {
1839  public:
1840   DECLARE_NODE_TYPE(CompareOperation)
1841
1842   Token::Value op() const { return op_; }
1843   Expression* left() const { return left_; }
1844   Expression* right() const { return right_; }
1845   virtual int position() const { return pos_; }
1846
1847   // Type feedback information.
1848   void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1849   bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
1850   bool IsObjectCompare() { return compare_type_ == OBJECT_ONLY; }
1851
1852   // Match special cases.
1853   bool IsLiteralCompareTypeof(Expression** expr, Handle<String>* check);
1854   bool IsLiteralCompareUndefined(Expression** expr);
1855   bool IsLiteralCompareNull(Expression** expr);
1856
1857  protected:
1858   template<class> friend class AstNodeFactory;
1859
1860   CompareOperation(Isolate* isolate,
1861                    Token::Value op,
1862                    Expression* left,
1863                    Expression* right,
1864                    int pos)
1865       : Expression(isolate),
1866         op_(op),
1867         left_(left),
1868         right_(right),
1869         pos_(pos),
1870         compare_type_(NONE) {
1871     ASSERT(Token::IsCompareOp(op));
1872   }
1873
1874  private:
1875   Token::Value op_;
1876   Expression* left_;
1877   Expression* right_;
1878   int pos_;
1879
1880   enum CompareTypeFeedback { NONE, SMI_ONLY, OBJECT_ONLY };
1881   CompareTypeFeedback compare_type_;
1882 };
1883
1884
1885 class Conditional: public Expression {
1886  public:
1887   DECLARE_NODE_TYPE(Conditional)
1888
1889   Expression* condition() const { return condition_; }
1890   Expression* then_expression() const { return then_expression_; }
1891   Expression* else_expression() const { return else_expression_; }
1892
1893   int then_expression_position() const { return then_expression_position_; }
1894   int else_expression_position() const { return else_expression_position_; }
1895
1896   int ThenId() const { return then_id_; }
1897   int ElseId() const { return else_id_; }
1898
1899  protected:
1900   template<class> friend class AstNodeFactory;
1901
1902   Conditional(Isolate* isolate,
1903               Expression* condition,
1904               Expression* then_expression,
1905               Expression* else_expression,
1906               int then_expression_position,
1907               int else_expression_position)
1908       : Expression(isolate),
1909         condition_(condition),
1910         then_expression_(then_expression),
1911         else_expression_(else_expression),
1912         then_expression_position_(then_expression_position),
1913         else_expression_position_(else_expression_position),
1914         then_id_(GetNextId(isolate)),
1915         else_id_(GetNextId(isolate)) { }
1916
1917  private:
1918   Expression* condition_;
1919   Expression* then_expression_;
1920   Expression* else_expression_;
1921   int then_expression_position_;
1922   int else_expression_position_;
1923   int then_id_;
1924   int else_id_;
1925 };
1926
1927
1928 class Assignment: public Expression {
1929  public:
1930   DECLARE_NODE_TYPE(Assignment)
1931
1932   Assignment* AsSimpleAssignment() { return !is_compound() ? this : NULL; }
1933
1934   Token::Value binary_op() const;
1935
1936   Token::Value op() const { return op_; }
1937   Expression* target() const { return target_; }
1938   Expression* value() const { return value_; }
1939   virtual int position() const { return pos_; }
1940   BinaryOperation* binary_operation() const { return binary_operation_; }
1941
1942   // This check relies on the definition order of token in token.h.
1943   bool is_compound() const { return op() > Token::ASSIGN; }
1944
1945   // An initialization block is a series of statments of the form
1946   // x.y.z.a = ...; x.y.z.b = ...; etc. The parser marks the beginning and
1947   // ending of these blocks to allow for optimizations of initialization
1948   // blocks.
1949   bool starts_initialization_block() { return block_start_; }
1950   bool ends_initialization_block() { return block_end_; }
1951   void mark_block_start() { block_start_ = true; }
1952   void mark_block_end() { block_end_ = true; }
1953
1954   // Type feedback information.
1955   void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1956   virtual bool IsMonomorphic() { return is_monomorphic_; }
1957   virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
1958
1959   // Bailout support.
1960   int CompoundLoadId() const { return compound_load_id_; }
1961   int AssignmentId() const { return assignment_id_; }
1962
1963  protected:
1964   template<class> friend class AstNodeFactory;
1965
1966   Assignment(Isolate* isolate,
1967              Token::Value op,
1968              Expression* target,
1969              Expression* value,
1970              int pos);
1971
1972   template<class Visitor>
1973   void Init(Isolate* isolate, AstNodeFactory<Visitor>* factory) {
1974     ASSERT(Token::IsAssignmentOp(op_));
1975     if (is_compound()) {
1976       binary_operation_ =
1977           factory->NewBinaryOperation(binary_op(), target_, value_, pos_ + 1);
1978       compound_load_id_ = GetNextId(isolate);
1979     }
1980   }
1981
1982  private:
1983   Token::Value op_;
1984   Expression* target_;
1985   Expression* value_;
1986   int pos_;
1987   BinaryOperation* binary_operation_;
1988   int compound_load_id_;
1989   int assignment_id_;
1990
1991   bool block_start_;
1992   bool block_end_;
1993
1994   bool is_monomorphic_;
1995   SmallMapList receiver_types_;
1996 };
1997
1998
1999 class Throw: public Expression {
2000  public:
2001   DECLARE_NODE_TYPE(Throw)
2002
2003   Expression* exception() const { return exception_; }
2004   virtual int position() const { return pos_; }
2005
2006  protected:
2007   template<class> friend class AstNodeFactory;
2008
2009   Throw(Isolate* isolate, Expression* exception, int pos)
2010       : Expression(isolate), exception_(exception), pos_(pos) {}
2011
2012  private:
2013   Expression* exception_;
2014   int pos_;
2015 };
2016
2017
2018 class FunctionLiteral: public Expression {
2019  public:
2020   enum Type {
2021     ANONYMOUS_EXPRESSION,
2022     NAMED_EXPRESSION,
2023     DECLARATION
2024   };
2025
2026   enum ParameterFlag {
2027     kNoDuplicateParameters = 0,
2028     kHasDuplicateParameters = 1
2029   };
2030
2031   enum IsFunctionFlag {
2032     kGlobalOrEval,
2033     kIsFunction
2034   };
2035
2036   DECLARE_NODE_TYPE(FunctionLiteral)
2037
2038   Handle<String> name() const { return name_; }
2039   Scope* scope() const { return scope_; }
2040   ZoneList<Statement*>* body() const { return body_; }
2041   void set_function_token_position(int pos) { function_token_position_ = pos; }
2042   int function_token_position() const { return function_token_position_; }
2043   int start_position() const;
2044   int end_position() const;
2045   int SourceSize() const { return end_position() - start_position(); }
2046   bool is_expression() const { return IsExpression::decode(bitfield_); }
2047   bool is_anonymous() const { return IsAnonymous::decode(bitfield_); }
2048   bool is_classic_mode() const { return language_mode() == CLASSIC_MODE; }
2049   LanguageMode language_mode() const;
2050
2051   int materialized_literal_count() { return materialized_literal_count_; }
2052   int expected_property_count() { return expected_property_count_; }
2053   int handler_count() { return handler_count_; }
2054   bool has_only_simple_this_property_assignments() {
2055     return HasOnlySimpleThisPropertyAssignments::decode(bitfield_);
2056   }
2057   Handle<FixedArray> this_property_assignments() {
2058       return this_property_assignments_;
2059   }
2060   int parameter_count() { return parameter_count_; }
2061
2062   bool AllowsLazyCompilation();
2063
2064   Handle<String> debug_name() const {
2065     if (name_->length() > 0) return name_;
2066     return inferred_name();
2067   }
2068
2069   Handle<String> inferred_name() const { return inferred_name_; }
2070   void set_inferred_name(Handle<String> inferred_name) {
2071     inferred_name_ = inferred_name;
2072   }
2073
2074   bool pretenure() { return Pretenure::decode(bitfield_); }
2075   void set_pretenure() { bitfield_ |= Pretenure::encode(true); }
2076
2077   bool has_duplicate_parameters() {
2078     return HasDuplicateParameters::decode(bitfield_);
2079   }
2080
2081   bool is_function() { return IsFunction::decode(bitfield_) == kIsFunction; }
2082
2083   int ast_node_count() { return ast_properties_.node_count(); }
2084   AstProperties::Flags* flags() { return ast_properties_.flags(); }
2085   void set_ast_properties(AstProperties* ast_properties) {
2086     ast_properties_ = *ast_properties;
2087   }
2088
2089  protected:
2090   template<class> friend class AstNodeFactory;
2091
2092   FunctionLiteral(Isolate* isolate,
2093                   Handle<String> name,
2094                   Scope* scope,
2095                   ZoneList<Statement*>* body,
2096                   int materialized_literal_count,
2097                   int expected_property_count,
2098                   int handler_count,
2099                   bool has_only_simple_this_property_assignments,
2100                   Handle<FixedArray> this_property_assignments,
2101                   int parameter_count,
2102                   Type type,
2103                   ParameterFlag has_duplicate_parameters,
2104                   IsFunctionFlag is_function)
2105       : Expression(isolate),
2106         name_(name),
2107         scope_(scope),
2108         body_(body),
2109         this_property_assignments_(this_property_assignments),
2110         inferred_name_(isolate->factory()->empty_string()),
2111         materialized_literal_count_(materialized_literal_count),
2112         expected_property_count_(expected_property_count),
2113         handler_count_(handler_count),
2114         parameter_count_(parameter_count),
2115         function_token_position_(RelocInfo::kNoPosition) {
2116     bitfield_ =
2117         HasOnlySimpleThisPropertyAssignments::encode(
2118             has_only_simple_this_property_assignments) |
2119         IsExpression::encode(type != DECLARATION) |
2120         IsAnonymous::encode(type == ANONYMOUS_EXPRESSION) |
2121         Pretenure::encode(false) |
2122         HasDuplicateParameters::encode(has_duplicate_parameters) |
2123         IsFunction::encode(is_function);
2124   }
2125
2126  private:
2127   Handle<String> name_;
2128   Scope* scope_;
2129   ZoneList<Statement*>* body_;
2130   Handle<FixedArray> this_property_assignments_;
2131   Handle<String> inferred_name_;
2132   AstProperties ast_properties_;
2133
2134   int materialized_literal_count_;
2135   int expected_property_count_;
2136   int handler_count_;
2137   int parameter_count_;
2138   int function_token_position_;
2139
2140   unsigned bitfield_;
2141   class HasOnlySimpleThisPropertyAssignments: public BitField<bool, 0, 1> {};
2142   class IsExpression: public BitField<bool, 1, 1> {};
2143   class IsAnonymous: public BitField<bool, 2, 1> {};
2144   class Pretenure: public BitField<bool, 3, 1> {};
2145   class HasDuplicateParameters: public BitField<ParameterFlag, 4, 1> {};
2146   class IsFunction: public BitField<IsFunctionFlag, 5, 1> {};
2147 };
2148
2149
2150 class SharedFunctionInfoLiteral: public Expression {
2151  public:
2152   DECLARE_NODE_TYPE(SharedFunctionInfoLiteral)
2153
2154   Handle<SharedFunctionInfo> shared_function_info() const {
2155     return shared_function_info_;
2156   }
2157
2158  protected:
2159   template<class> friend class AstNodeFactory;
2160
2161   SharedFunctionInfoLiteral(
2162       Isolate* isolate,
2163       Handle<SharedFunctionInfo> shared_function_info)
2164       : Expression(isolate),
2165         shared_function_info_(shared_function_info) { }
2166
2167  private:
2168   Handle<SharedFunctionInfo> shared_function_info_;
2169 };
2170
2171
2172 class ThisFunction: public Expression {
2173  public:
2174   DECLARE_NODE_TYPE(ThisFunction)
2175
2176  protected:
2177   template<class> friend class AstNodeFactory;
2178
2179   explicit ThisFunction(Isolate* isolate): Expression(isolate) {}
2180 };
2181
2182 #undef DECLARE_NODE_TYPE
2183
2184
2185 // ----------------------------------------------------------------------------
2186 // Regular expressions
2187
2188
2189 class RegExpVisitor BASE_EMBEDDED {
2190  public:
2191   virtual ~RegExpVisitor() { }
2192 #define MAKE_CASE(Name)                                              \
2193   virtual void* Visit##Name(RegExp##Name*, void* data) = 0;
2194   FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
2195 #undef MAKE_CASE
2196 };
2197
2198
2199 class RegExpTree: public ZoneObject {
2200  public:
2201   static const int kInfinity = kMaxInt;
2202   virtual ~RegExpTree() { }
2203   virtual void* Accept(RegExpVisitor* visitor, void* data) = 0;
2204   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2205                              RegExpNode* on_success) = 0;
2206   virtual bool IsTextElement() { return false; }
2207   virtual bool IsAnchoredAtStart() { return false; }
2208   virtual bool IsAnchoredAtEnd() { return false; }
2209   virtual int min_match() = 0;
2210   virtual int max_match() = 0;
2211   // Returns the interval of registers used for captures within this
2212   // expression.
2213   virtual Interval CaptureRegisters() { return Interval::Empty(); }
2214   virtual void AppendToText(RegExpText* text);
2215   SmartArrayPointer<const char> ToString();
2216 #define MAKE_ASTYPE(Name)                                                  \
2217   virtual RegExp##Name* As##Name();                                        \
2218   virtual bool Is##Name();
2219   FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE)
2220 #undef MAKE_ASTYPE
2221 };
2222
2223
2224 class RegExpDisjunction: public RegExpTree {
2225  public:
2226   explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives);
2227   virtual void* Accept(RegExpVisitor* visitor, void* data);
2228   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2229                              RegExpNode* on_success);
2230   virtual RegExpDisjunction* AsDisjunction();
2231   virtual Interval CaptureRegisters();
2232   virtual bool IsDisjunction();
2233   virtual bool IsAnchoredAtStart();
2234   virtual bool IsAnchoredAtEnd();
2235   virtual int min_match() { return min_match_; }
2236   virtual int max_match() { return max_match_; }
2237   ZoneList<RegExpTree*>* alternatives() { return alternatives_; }
2238  private:
2239   ZoneList<RegExpTree*>* alternatives_;
2240   int min_match_;
2241   int max_match_;
2242 };
2243
2244
2245 class RegExpAlternative: public RegExpTree {
2246  public:
2247   explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes);
2248   virtual void* Accept(RegExpVisitor* visitor, void* data);
2249   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2250                              RegExpNode* on_success);
2251   virtual RegExpAlternative* AsAlternative();
2252   virtual Interval CaptureRegisters();
2253   virtual bool IsAlternative();
2254   virtual bool IsAnchoredAtStart();
2255   virtual bool IsAnchoredAtEnd();
2256   virtual int min_match() { return min_match_; }
2257   virtual int max_match() { return max_match_; }
2258   ZoneList<RegExpTree*>* nodes() { return nodes_; }
2259  private:
2260   ZoneList<RegExpTree*>* nodes_;
2261   int min_match_;
2262   int max_match_;
2263 };
2264
2265
2266 class RegExpAssertion: public RegExpTree {
2267  public:
2268   enum Type {
2269     START_OF_LINE,
2270     START_OF_INPUT,
2271     END_OF_LINE,
2272     END_OF_INPUT,
2273     BOUNDARY,
2274     NON_BOUNDARY
2275   };
2276   explicit RegExpAssertion(Type type) : type_(type) { }
2277   virtual void* Accept(RegExpVisitor* visitor, void* data);
2278   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2279                              RegExpNode* on_success);
2280   virtual RegExpAssertion* AsAssertion();
2281   virtual bool IsAssertion();
2282   virtual bool IsAnchoredAtStart();
2283   virtual bool IsAnchoredAtEnd();
2284   virtual int min_match() { return 0; }
2285   virtual int max_match() { return 0; }
2286   Type type() { return type_; }
2287  private:
2288   Type type_;
2289 };
2290
2291
2292 class CharacterSet BASE_EMBEDDED {
2293  public:
2294   explicit CharacterSet(uc16 standard_set_type)
2295       : ranges_(NULL),
2296         standard_set_type_(standard_set_type) {}
2297   explicit CharacterSet(ZoneList<CharacterRange>* ranges)
2298       : ranges_(ranges),
2299         standard_set_type_(0) {}
2300   ZoneList<CharacterRange>* ranges();
2301   uc16 standard_set_type() { return standard_set_type_; }
2302   void set_standard_set_type(uc16 special_set_type) {
2303     standard_set_type_ = special_set_type;
2304   }
2305   bool is_standard() { return standard_set_type_ != 0; }
2306   void Canonicalize();
2307  private:
2308   ZoneList<CharacterRange>* ranges_;
2309   // If non-zero, the value represents a standard set (e.g., all whitespace
2310   // characters) without having to expand the ranges.
2311   uc16 standard_set_type_;
2312 };
2313
2314
2315 class RegExpCharacterClass: public RegExpTree {
2316  public:
2317   RegExpCharacterClass(ZoneList<CharacterRange>* ranges, bool is_negated)
2318       : set_(ranges),
2319         is_negated_(is_negated) { }
2320   explicit RegExpCharacterClass(uc16 type)
2321       : set_(type),
2322         is_negated_(false) { }
2323   virtual void* Accept(RegExpVisitor* visitor, void* data);
2324   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2325                              RegExpNode* on_success);
2326   virtual RegExpCharacterClass* AsCharacterClass();
2327   virtual bool IsCharacterClass();
2328   virtual bool IsTextElement() { return true; }
2329   virtual int min_match() { return 1; }
2330   virtual int max_match() { return 1; }
2331   virtual void AppendToText(RegExpText* text);
2332   CharacterSet character_set() { return set_; }
2333   // TODO(lrn): Remove need for complex version if is_standard that
2334   // recognizes a mangled standard set and just do { return set_.is_special(); }
2335   bool is_standard();
2336   // Returns a value representing the standard character set if is_standard()
2337   // returns true.
2338   // Currently used values are:
2339   // s : unicode whitespace
2340   // S : unicode non-whitespace
2341   // w : ASCII word character (digit, letter, underscore)
2342   // W : non-ASCII word character
2343   // d : ASCII digit
2344   // D : non-ASCII digit
2345   // . : non-unicode non-newline
2346   // * : All characters
2347   uc16 standard_type() { return set_.standard_set_type(); }
2348   ZoneList<CharacterRange>* ranges() { return set_.ranges(); }
2349   bool is_negated() { return is_negated_; }
2350
2351  private:
2352   CharacterSet set_;
2353   bool is_negated_;
2354 };
2355
2356
2357 class RegExpAtom: public RegExpTree {
2358  public:
2359   explicit RegExpAtom(Vector<const uc16> data) : data_(data) { }
2360   virtual void* Accept(RegExpVisitor* visitor, void* data);
2361   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2362                              RegExpNode* on_success);
2363   virtual RegExpAtom* AsAtom();
2364   virtual bool IsAtom();
2365   virtual bool IsTextElement() { return true; }
2366   virtual int min_match() { return data_.length(); }
2367   virtual int max_match() { return data_.length(); }
2368   virtual void AppendToText(RegExpText* text);
2369   Vector<const uc16> data() { return data_; }
2370   int length() { return data_.length(); }
2371  private:
2372   Vector<const uc16> data_;
2373 };
2374
2375
2376 class RegExpText: public RegExpTree {
2377  public:
2378   RegExpText() : elements_(2), length_(0) {}
2379   virtual void* Accept(RegExpVisitor* visitor, void* data);
2380   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2381                              RegExpNode* on_success);
2382   virtual RegExpText* AsText();
2383   virtual bool IsText();
2384   virtual bool IsTextElement() { return true; }
2385   virtual int min_match() { return length_; }
2386   virtual int max_match() { return length_; }
2387   virtual void AppendToText(RegExpText* text);
2388   void AddElement(TextElement elm)  {
2389     elements_.Add(elm);
2390     length_ += elm.length();
2391   }
2392   ZoneList<TextElement>* elements() { return &elements_; }
2393  private:
2394   ZoneList<TextElement> elements_;
2395   int length_;
2396 };
2397
2398
2399 class RegExpQuantifier: public RegExpTree {
2400  public:
2401   enum Type { GREEDY, NON_GREEDY, POSSESSIVE };
2402   RegExpQuantifier(int min, int max, Type type, RegExpTree* body)
2403       : body_(body),
2404         min_(min),
2405         max_(max),
2406         min_match_(min * body->min_match()),
2407         type_(type) {
2408     if (max > 0 && body->max_match() > kInfinity / max) {
2409       max_match_ = kInfinity;
2410     } else {
2411       max_match_ = max * body->max_match();
2412     }
2413   }
2414   virtual void* Accept(RegExpVisitor* visitor, void* data);
2415   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2416                              RegExpNode* on_success);
2417   static RegExpNode* ToNode(int min,
2418                             int max,
2419                             bool is_greedy,
2420                             RegExpTree* body,
2421                             RegExpCompiler* compiler,
2422                             RegExpNode* on_success,
2423                             bool not_at_start = false);
2424   virtual RegExpQuantifier* AsQuantifier();
2425   virtual Interval CaptureRegisters();
2426   virtual bool IsQuantifier();
2427   virtual int min_match() { return min_match_; }
2428   virtual int max_match() { return max_match_; }
2429   int min() { return min_; }
2430   int max() { return max_; }
2431   bool is_possessive() { return type_ == POSSESSIVE; }
2432   bool is_non_greedy() { return type_ == NON_GREEDY; }
2433   bool is_greedy() { return type_ == GREEDY; }
2434   RegExpTree* body() { return body_; }
2435
2436  private:
2437   RegExpTree* body_;
2438   int min_;
2439   int max_;
2440   int min_match_;
2441   int max_match_;
2442   Type type_;
2443 };
2444
2445
2446 class RegExpCapture: public RegExpTree {
2447  public:
2448   explicit RegExpCapture(RegExpTree* body, int index)
2449       : body_(body), index_(index) { }
2450   virtual void* Accept(RegExpVisitor* visitor, void* data);
2451   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2452                              RegExpNode* on_success);
2453   static RegExpNode* ToNode(RegExpTree* body,
2454                             int index,
2455                             RegExpCompiler* compiler,
2456                             RegExpNode* on_success);
2457   virtual RegExpCapture* AsCapture();
2458   virtual bool IsAnchoredAtStart();
2459   virtual bool IsAnchoredAtEnd();
2460   virtual Interval CaptureRegisters();
2461   virtual bool IsCapture();
2462   virtual int min_match() { return body_->min_match(); }
2463   virtual int max_match() { return body_->max_match(); }
2464   RegExpTree* body() { return body_; }
2465   int index() { return index_; }
2466   static int StartRegister(int index) { return index * 2; }
2467   static int EndRegister(int index) { return index * 2 + 1; }
2468
2469  private:
2470   RegExpTree* body_;
2471   int index_;
2472 };
2473
2474
2475 class RegExpLookahead: public RegExpTree {
2476  public:
2477   RegExpLookahead(RegExpTree* body,
2478                   bool is_positive,
2479                   int capture_count,
2480                   int capture_from)
2481       : body_(body),
2482         is_positive_(is_positive),
2483         capture_count_(capture_count),
2484         capture_from_(capture_from) { }
2485
2486   virtual void* Accept(RegExpVisitor* visitor, void* data);
2487   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2488                              RegExpNode* on_success);
2489   virtual RegExpLookahead* AsLookahead();
2490   virtual Interval CaptureRegisters();
2491   virtual bool IsLookahead();
2492   virtual bool IsAnchoredAtStart();
2493   virtual int min_match() { return 0; }
2494   virtual int max_match() { return 0; }
2495   RegExpTree* body() { return body_; }
2496   bool is_positive() { return is_positive_; }
2497   int capture_count() { return capture_count_; }
2498   int capture_from() { return capture_from_; }
2499
2500  private:
2501   RegExpTree* body_;
2502   bool is_positive_;
2503   int capture_count_;
2504   int capture_from_;
2505 };
2506
2507
2508 class RegExpBackReference: public RegExpTree {
2509  public:
2510   explicit RegExpBackReference(RegExpCapture* capture)
2511       : capture_(capture) { }
2512   virtual void* Accept(RegExpVisitor* visitor, void* data);
2513   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2514                              RegExpNode* on_success);
2515   virtual RegExpBackReference* AsBackReference();
2516   virtual bool IsBackReference();
2517   virtual int min_match() { return 0; }
2518   virtual int max_match() { return capture_->max_match(); }
2519   int index() { return capture_->index(); }
2520   RegExpCapture* capture() { return capture_; }
2521  private:
2522   RegExpCapture* capture_;
2523 };
2524
2525
2526 class RegExpEmpty: public RegExpTree {
2527  public:
2528   RegExpEmpty() { }
2529   virtual void* Accept(RegExpVisitor* visitor, void* data);
2530   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2531                              RegExpNode* on_success);
2532   virtual RegExpEmpty* AsEmpty();
2533   virtual bool IsEmpty();
2534   virtual int min_match() { return 0; }
2535   virtual int max_match() { return 0; }
2536   static RegExpEmpty* GetInstance() {
2537     static RegExpEmpty* instance = ::new RegExpEmpty();
2538     return instance;
2539   }
2540 };
2541
2542
2543 // ----------------------------------------------------------------------------
2544 // Out-of-line inline constructors (to side-step cyclic dependencies).
2545
2546 inline ModuleVariable::ModuleVariable(VariableProxy* proxy)
2547     : Module(proxy->interface()),
2548       proxy_(proxy) {
2549 }
2550
2551
2552 // ----------------------------------------------------------------------------
2553 // Basic visitor
2554 // - leaf node visitors are abstract.
2555
2556 class AstVisitor BASE_EMBEDDED {
2557  public:
2558   AstVisitor() : isolate_(Isolate::Current()), stack_overflow_(false) { }
2559   virtual ~AstVisitor() { }
2560
2561   // Stack overflow check and dynamic dispatch.
2562   void Visit(AstNode* node) { if (!CheckStackOverflow()) node->Accept(this); }
2563
2564   // Iteration left-to-right.
2565   virtual void VisitDeclarations(ZoneList<Declaration*>* declarations);
2566   virtual void VisitStatements(ZoneList<Statement*>* statements);
2567   virtual void VisitExpressions(ZoneList<Expression*>* expressions);
2568
2569   // Stack overflow tracking support.
2570   bool HasStackOverflow() const { return stack_overflow_; }
2571   bool CheckStackOverflow();
2572
2573   // If a stack-overflow exception is encountered when visiting a
2574   // node, calling SetStackOverflow will make sure that the visitor
2575   // bails out without visiting more nodes.
2576   void SetStackOverflow() { stack_overflow_ = true; }
2577   void ClearStackOverflow() { stack_overflow_ = false; }
2578
2579   // Individual AST nodes.
2580 #define DEF_VISIT(type)                         \
2581   virtual void Visit##type(type* node) = 0;
2582   AST_NODE_LIST(DEF_VISIT)
2583 #undef DEF_VISIT
2584
2585  protected:
2586   Isolate* isolate() { return isolate_; }
2587
2588  private:
2589   Isolate* isolate_;
2590   bool stack_overflow_;
2591 };
2592
2593
2594 // ----------------------------------------------------------------------------
2595 // Construction time visitor.
2596
2597 class AstConstructionVisitor BASE_EMBEDDED {
2598  public:
2599   AstConstructionVisitor() { }
2600
2601   AstProperties* ast_properties() { return &properties_; }
2602
2603  private:
2604   template<class> friend class AstNodeFactory;
2605
2606   // Node visitors.
2607 #define DEF_VISIT(type) \
2608   void Visit##type(type* node);
2609   AST_NODE_LIST(DEF_VISIT)
2610 #undef DEF_VISIT
2611
2612   void increase_node_count() { properties_.add_node_count(1); }
2613   void add_flag(AstPropertiesFlag flag) { properties_.flags()->Add(flag); }
2614
2615   AstProperties properties_;
2616 };
2617
2618
2619 class AstNullVisitor BASE_EMBEDDED {
2620  public:
2621   // Node visitors.
2622 #define DEF_VISIT(type) \
2623   void Visit##type(type* node) {}
2624   AST_NODE_LIST(DEF_VISIT)
2625 #undef DEF_VISIT
2626 };
2627
2628
2629
2630 // ----------------------------------------------------------------------------
2631 // AstNode factory
2632
2633 template<class Visitor>
2634 class AstNodeFactory BASE_EMBEDDED {
2635  public:
2636   explicit AstNodeFactory(Isolate* isolate)
2637       : isolate_(isolate),
2638         zone_(isolate_->zone()) { }
2639
2640   Visitor* visitor() { return &visitor_; }
2641
2642 #define VISIT_AND_RETURN(NodeType, node) \
2643   visitor_.Visit##NodeType((node)); \
2644   return node;
2645
2646   VariableDeclaration* NewVariableDeclaration(VariableProxy* proxy,
2647                                               VariableMode mode,
2648                                               Scope* scope) {
2649     VariableDeclaration* decl =
2650         new(zone_) VariableDeclaration(proxy, mode, scope);
2651     VISIT_AND_RETURN(VariableDeclaration, decl)
2652   }
2653
2654   FunctionDeclaration* NewFunctionDeclaration(VariableProxy* proxy,
2655                                               VariableMode mode,
2656                                               FunctionLiteral* fun,
2657                                               Scope* scope) {
2658     FunctionDeclaration* decl =
2659         new(zone_) FunctionDeclaration(proxy, mode, fun, scope);
2660     VISIT_AND_RETURN(FunctionDeclaration, decl)
2661   }
2662
2663   ModuleDeclaration* NewModuleDeclaration(VariableProxy* proxy,
2664                                           Module* module,
2665                                           Scope* scope) {
2666     ModuleDeclaration* decl =
2667         new(zone_) ModuleDeclaration(proxy, module, scope);
2668     VISIT_AND_RETURN(ModuleDeclaration, decl)
2669   }
2670
2671   ImportDeclaration* NewImportDeclaration(VariableProxy* proxy,
2672                                           Module* module,
2673                                           Scope* scope) {
2674     ImportDeclaration* decl =
2675         new(zone_) ImportDeclaration(proxy, module, scope);
2676     VISIT_AND_RETURN(ImportDeclaration, decl)
2677   }
2678
2679   ExportDeclaration* NewExportDeclaration(VariableProxy* proxy,
2680                                           Scope* scope) {
2681     ExportDeclaration* decl =
2682         new(zone_) ExportDeclaration(proxy, scope);
2683     VISIT_AND_RETURN(ExportDeclaration, decl)
2684   }
2685
2686   ModuleLiteral* NewModuleLiteral(Block* body, Interface* interface) {
2687     ModuleLiteral* module = new(zone_) ModuleLiteral(body, interface);
2688     VISIT_AND_RETURN(ModuleLiteral, module)
2689   }
2690
2691   ModuleVariable* NewModuleVariable(VariableProxy* proxy) {
2692     ModuleVariable* module = new(zone_) ModuleVariable(proxy);
2693     VISIT_AND_RETURN(ModuleVariable, module)
2694   }
2695
2696   ModulePath* NewModulePath(Module* origin, Handle<String> name) {
2697     ModulePath* module = new(zone_) ModulePath(origin, name);
2698     VISIT_AND_RETURN(ModulePath, module)
2699   }
2700
2701   ModuleUrl* NewModuleUrl(Handle<String> url) {
2702     ModuleUrl* module = new(zone_) ModuleUrl(url);
2703     VISIT_AND_RETURN(ModuleUrl, module)
2704   }
2705
2706   Block* NewBlock(ZoneStringList* labels,
2707                   int capacity,
2708                   bool is_initializer_block) {
2709     Block* block = new(zone_) Block(
2710         isolate_, labels, capacity, is_initializer_block);
2711     VISIT_AND_RETURN(Block, block)
2712   }
2713
2714 #define STATEMENT_WITH_LABELS(NodeType) \
2715   NodeType* New##NodeType(ZoneStringList* labels) { \
2716     NodeType* stmt = new(zone_) NodeType(isolate_, labels); \
2717     VISIT_AND_RETURN(NodeType, stmt); \
2718   }
2719   STATEMENT_WITH_LABELS(DoWhileStatement)
2720   STATEMENT_WITH_LABELS(WhileStatement)
2721   STATEMENT_WITH_LABELS(ForStatement)
2722   STATEMENT_WITH_LABELS(ForInStatement)
2723   STATEMENT_WITH_LABELS(SwitchStatement)
2724 #undef STATEMENT_WITH_LABELS
2725
2726   ExpressionStatement* NewExpressionStatement(Expression* expression) {
2727     ExpressionStatement* stmt = new(zone_) ExpressionStatement(expression);
2728     VISIT_AND_RETURN(ExpressionStatement, stmt)
2729   }
2730
2731   ContinueStatement* NewContinueStatement(IterationStatement* target) {
2732     ContinueStatement* stmt = new(zone_) ContinueStatement(target);
2733     VISIT_AND_RETURN(ContinueStatement, stmt)
2734   }
2735
2736   BreakStatement* NewBreakStatement(BreakableStatement* target) {
2737     BreakStatement* stmt = new(zone_) BreakStatement(target);
2738     VISIT_AND_RETURN(BreakStatement, stmt)
2739   }
2740
2741   ReturnStatement* NewReturnStatement(Expression* expression) {
2742     ReturnStatement* stmt = new(zone_) ReturnStatement(expression);
2743     VISIT_AND_RETURN(ReturnStatement, stmt)
2744   }
2745
2746   WithStatement* NewWithStatement(Expression* expression,
2747                                   Statement* statement) {
2748     WithStatement* stmt = new(zone_) WithStatement(expression, statement);
2749     VISIT_AND_RETURN(WithStatement, stmt)
2750   }
2751
2752   IfStatement* NewIfStatement(Expression* condition,
2753                               Statement* then_statement,
2754                               Statement* else_statement) {
2755     IfStatement* stmt = new(zone_) IfStatement(
2756         isolate_, condition, then_statement, else_statement);
2757     VISIT_AND_RETURN(IfStatement, stmt)
2758   }
2759
2760   TryCatchStatement* NewTryCatchStatement(int index,
2761                                           Block* try_block,
2762                                           Scope* scope,
2763                                           Variable* variable,
2764                                           Block* catch_block) {
2765     TryCatchStatement* stmt = new(zone_) TryCatchStatement(
2766         index, try_block, scope, variable, catch_block);
2767     VISIT_AND_RETURN(TryCatchStatement, stmt)
2768   }
2769
2770   TryFinallyStatement* NewTryFinallyStatement(int index,
2771                                               Block* try_block,
2772                                               Block* finally_block) {
2773     TryFinallyStatement* stmt =
2774         new(zone_) TryFinallyStatement(index, try_block, finally_block);
2775     VISIT_AND_RETURN(TryFinallyStatement, stmt)
2776   }
2777
2778   DebuggerStatement* NewDebuggerStatement() {
2779     DebuggerStatement* stmt = new(zone_) DebuggerStatement();
2780     VISIT_AND_RETURN(DebuggerStatement, stmt)
2781   }
2782
2783   EmptyStatement* NewEmptyStatement() {
2784     return new(zone_) EmptyStatement();
2785   }
2786
2787   Literal* NewLiteral(Handle<Object> handle) {
2788     Literal* lit = new(zone_) Literal(isolate_, handle);
2789     VISIT_AND_RETURN(Literal, lit)
2790   }
2791
2792   Literal* NewNumberLiteral(double number) {
2793     return NewLiteral(isolate_->factory()->NewNumber(number, TENURED));
2794   }
2795
2796   ObjectLiteral* NewObjectLiteral(
2797       Handle<FixedArray> constant_properties,
2798       ZoneList<ObjectLiteral::Property*>* properties,
2799       int literal_index,
2800       bool is_simple,
2801       bool fast_elements,
2802       int depth,
2803       bool has_function) {
2804     ObjectLiteral* lit = new(zone_) ObjectLiteral(
2805         isolate_, constant_properties, properties, literal_index,
2806         is_simple, fast_elements, depth, has_function);
2807     VISIT_AND_RETURN(ObjectLiteral, lit)
2808   }
2809
2810   ObjectLiteral::Property* NewObjectLiteralProperty(bool is_getter,
2811                                                     FunctionLiteral* value) {
2812     ObjectLiteral::Property* prop =
2813         new(zone_) ObjectLiteral::Property(is_getter, value);
2814     prop->set_key(NewLiteral(value->name()));
2815     return prop;  // Not an AST node, will not be visited.
2816   }
2817
2818   RegExpLiteral* NewRegExpLiteral(Handle<String> pattern,
2819                                   Handle<String> flags,
2820                                   int literal_index) {
2821     RegExpLiteral* lit =
2822         new(zone_) RegExpLiteral(isolate_, pattern, flags, literal_index);
2823     VISIT_AND_RETURN(RegExpLiteral, lit);
2824   }
2825
2826   ArrayLiteral* NewArrayLiteral(Handle<FixedArray> constant_elements,
2827                                 ZoneList<Expression*>* values,
2828                                 int literal_index,
2829                                 bool is_simple,
2830                                 int depth) {
2831     ArrayLiteral* lit = new(zone_) ArrayLiteral(
2832         isolate_, constant_elements, values, literal_index, is_simple, depth);
2833     VISIT_AND_RETURN(ArrayLiteral, lit)
2834   }
2835
2836   VariableProxy* NewVariableProxy(Variable* var) {
2837     VariableProxy* proxy = new(zone_) VariableProxy(isolate_, var);
2838     VISIT_AND_RETURN(VariableProxy, proxy)
2839   }
2840
2841   VariableProxy* NewVariableProxy(Handle<String> name,
2842                                   bool is_this,
2843                                   int position = RelocInfo::kNoPosition,
2844                                   Interface* interface =
2845                                       Interface::NewValue()) {
2846     VariableProxy* proxy =
2847         new(zone_) VariableProxy(isolate_, name, is_this, position, interface);
2848     VISIT_AND_RETURN(VariableProxy, proxy)
2849   }
2850
2851   Property* NewProperty(Expression* obj, Expression* key, int pos) {
2852     Property* prop = new(zone_) Property(isolate_, obj, key, pos);
2853     VISIT_AND_RETURN(Property, prop)
2854   }
2855
2856   Call* NewCall(Expression* expression,
2857                 ZoneList<Expression*>* arguments,
2858                 int pos) {
2859     Call* call = new(zone_) Call(isolate_, expression, arguments, pos);
2860     VISIT_AND_RETURN(Call, call)
2861   }
2862
2863   CallNew* NewCallNew(Expression* expression,
2864                       ZoneList<Expression*>* arguments,
2865                       int pos) {
2866     CallNew* call = new(zone_) CallNew(isolate_, expression, arguments, pos);
2867     VISIT_AND_RETURN(CallNew, call)
2868   }
2869
2870   CallRuntime* NewCallRuntime(Handle<String> name,
2871                               const Runtime::Function* function,
2872                               ZoneList<Expression*>* arguments) {
2873     CallRuntime* call =
2874         new(zone_) CallRuntime(isolate_, name, function, arguments);
2875     VISIT_AND_RETURN(CallRuntime, call)
2876   }
2877
2878   UnaryOperation* NewUnaryOperation(Token::Value op,
2879                                     Expression* expression,
2880                                     int pos) {
2881     UnaryOperation* node =
2882         new(zone_) UnaryOperation(isolate_, op, expression, pos);
2883     VISIT_AND_RETURN(UnaryOperation, node)
2884   }
2885
2886   BinaryOperation* NewBinaryOperation(Token::Value op,
2887                                       Expression* left,
2888                                       Expression* right,
2889                                       int pos) {
2890     BinaryOperation* node =
2891         new(zone_) BinaryOperation(isolate_, op, left, right, pos);
2892     VISIT_AND_RETURN(BinaryOperation, node)
2893   }
2894
2895   CountOperation* NewCountOperation(Token::Value op,
2896                                     bool is_prefix,
2897                                     Expression* expr,
2898                                     int pos) {
2899     CountOperation* node =
2900         new(zone_) CountOperation(isolate_, op, is_prefix, expr, pos);
2901     VISIT_AND_RETURN(CountOperation, node)
2902   }
2903
2904   CompareOperation* NewCompareOperation(Token::Value op,
2905                                         Expression* left,
2906                                         Expression* right,
2907                                         int pos) {
2908     CompareOperation* node =
2909         new(zone_) CompareOperation(isolate_, op, left, right, pos);
2910     VISIT_AND_RETURN(CompareOperation, node)
2911   }
2912
2913   Conditional* NewConditional(Expression* condition,
2914                               Expression* then_expression,
2915                               Expression* else_expression,
2916                               int then_expression_position,
2917                               int else_expression_position) {
2918     Conditional* cond = new(zone_) Conditional(
2919         isolate_, condition, then_expression, else_expression,
2920         then_expression_position, else_expression_position);
2921     VISIT_AND_RETURN(Conditional, cond)
2922   }
2923
2924   Assignment* NewAssignment(Token::Value op,
2925                             Expression* target,
2926                             Expression* value,
2927                             int pos) {
2928     Assignment* assign =
2929         new(zone_) Assignment(isolate_, op, target, value, pos);
2930     assign->Init(isolate_, this);
2931     VISIT_AND_RETURN(Assignment, assign)
2932   }
2933
2934   Throw* NewThrow(Expression* exception, int pos) {
2935     Throw* t = new(zone_) Throw(isolate_, exception, pos);
2936     VISIT_AND_RETURN(Throw, t)
2937   }
2938
2939   FunctionLiteral* NewFunctionLiteral(
2940       Handle<String> name,
2941       Scope* scope,
2942       ZoneList<Statement*>* body,
2943       int materialized_literal_count,
2944       int expected_property_count,
2945       int handler_count,
2946       bool has_only_simple_this_property_assignments,
2947       Handle<FixedArray> this_property_assignments,
2948       int parameter_count,
2949       FunctionLiteral::ParameterFlag has_duplicate_parameters,
2950       FunctionLiteral::Type type,
2951       FunctionLiteral::IsFunctionFlag is_function) {
2952     FunctionLiteral* lit = new(zone_) FunctionLiteral(
2953         isolate_, name, scope, body,
2954         materialized_literal_count, expected_property_count, handler_count,
2955         has_only_simple_this_property_assignments, this_property_assignments,
2956         parameter_count, type, has_duplicate_parameters, is_function);
2957     // Top-level literal doesn't count for the AST's properties.
2958     if (is_function == FunctionLiteral::kIsFunction) {
2959       visitor_.VisitFunctionLiteral(lit);
2960     }
2961     return lit;
2962   }
2963
2964   SharedFunctionInfoLiteral* NewSharedFunctionInfoLiteral(
2965       Handle<SharedFunctionInfo> shared_function_info) {
2966     SharedFunctionInfoLiteral* lit =
2967         new(zone_) SharedFunctionInfoLiteral(isolate_, shared_function_info);
2968     VISIT_AND_RETURN(SharedFunctionInfoLiteral, lit)
2969   }
2970
2971   ThisFunction* NewThisFunction() {
2972     ThisFunction* fun = new(zone_) ThisFunction(isolate_);
2973     VISIT_AND_RETURN(ThisFunction, fun)
2974   }
2975
2976 #undef VISIT_AND_RETURN
2977
2978  private:
2979   Isolate* isolate_;
2980   Zone* zone_;
2981   Visitor visitor_;
2982 };
2983
2984
2985 } }  // namespace v8::internal
2986
2987 #endif  // V8_AST_H_