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