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