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