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