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