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