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