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