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