1// Copyright 2012 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6//     * Redistributions of source code must retain the above copyright
7//       notice, this list of conditions and the following disclaimer.
8//     * Redistributions in binary form must reproduce the above
9//       copyright notice, this list of conditions and the following
10//       disclaimer in the documentation and/or other materials provided
11//       with the distribution.
12//     * Neither the name of Google Inc. nor the names of its
13//       contributors may be used to endorse or promote products derived
14//       from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_AST_H_
29#define V8_AST_H_
30
31#include "v8.h"
32
33#include "assembler.h"
34#include "factory.h"
35#include "isolate.h"
36#include "jsregexp.h"
37#include "list-inl.h"
38#include "runtime.h"
39#include "small-pointer-list.h"
40#include "smart-array-pointer.h"
41#include "token.h"
42#include "utils.h"
43#include "variables.h"
44#include "interface.h"
45#include "zone-inl.h"
46
47namespace v8 {
48namespace internal {
49
50// The abstract syntax tree is an intermediate, light-weight
51// representation of the parsed JavaScript code suitable for
52// compilation to native code.
53
54// Nodes are allocated in a separate zone, which allows faster
55// allocation and constant-time deallocation of the entire syntax
56// tree.
57
58
59// ----------------------------------------------------------------------------
60// Nodes of the abstract syntax tree. Only concrete classes are
61// enumerated here.
62
63#define DECLARATION_NODE_LIST(V)                \
64  V(VariableDeclaration)                        \
65  V(FunctionDeclaration)                        \
66  V(ModuleDeclaration)                          \
67  V(ImportDeclaration)                          \
68  V(ExportDeclaration)                          \
69
70#define MODULE_NODE_LIST(V)                     \
71  V(ModuleLiteral)                              \
72  V(ModuleVariable)                             \
73  V(ModulePath)                                 \
74  V(ModuleUrl)
75
76#define STATEMENT_NODE_LIST(V)                  \
77  V(Block)                                      \
78  V(ExpressionStatement)                        \
79  V(EmptyStatement)                             \
80  V(IfStatement)                                \
81  V(ContinueStatement)                          \
82  V(BreakStatement)                             \
83  V(ReturnStatement)                            \
84  V(WithStatement)                              \
85  V(SwitchStatement)                            \
86  V(DoWhileStatement)                           \
87  V(WhileStatement)                             \
88  V(ForStatement)                               \
89  V(ForInStatement)                             \
90  V(TryCatchStatement)                          \
91  V(TryFinallyStatement)                        \
92  V(DebuggerStatement)
93
94#define EXPRESSION_NODE_LIST(V)                 \
95  V(FunctionLiteral)                            \
96  V(SharedFunctionInfoLiteral)                  \
97  V(Conditional)                                \
98  V(VariableProxy)                              \
99  V(Literal)                                    \
100  V(RegExpLiteral)                              \
101  V(ObjectLiteral)                              \
102  V(ArrayLiteral)                               \
103  V(Assignment)                                 \
104  V(Throw)                                      \
105  V(Property)                                   \
106  V(Call)                                       \
107  V(CallNew)                                    \
108  V(CallRuntime)                                \
109  V(UnaryOperation)                             \
110  V(CountOperation)                             \
111  V(BinaryOperation)                            \
112  V(CompareOperation)                           \
113  V(ThisFunction)
114
115#define AST_NODE_LIST(V)                        \
116  DECLARATION_NODE_LIST(V)                      \
117  MODULE_NODE_LIST(V)                           \
118  STATEMENT_NODE_LIST(V)                        \
119  EXPRESSION_NODE_LIST(V)
120
121// Forward declarations
122class AstConstructionVisitor;
123template<class> class AstNodeFactory;
124class AstVisitor;
125class Declaration;
126class Module;
127class BreakableStatement;
128class Expression;
129class IterationStatement;
130class MaterializedLiteral;
131class Statement;
132class TargetCollector;
133class TypeFeedbackOracle;
134
135class RegExpAlternative;
136class RegExpAssertion;
137class RegExpAtom;
138class RegExpBackReference;
139class RegExpCapture;
140class RegExpCharacterClass;
141class RegExpCompiler;
142class RegExpDisjunction;
143class RegExpEmpty;
144class RegExpLookahead;
145class RegExpQuantifier;
146class RegExpText;
147
148#define DEF_FORWARD_DECLARATION(type) class type;
149AST_NODE_LIST(DEF_FORWARD_DECLARATION)
150#undef DEF_FORWARD_DECLARATION
151
152
153// Typedef only introduced to avoid unreadable code.
154// Please do appreciate the required space in "> >".
155typedef ZoneList<Handle<String> > ZoneStringList;
156typedef ZoneList<Handle<Object> > ZoneObjectList;
157
158
159#define DECLARE_NODE_TYPE(type)                                         \
160  virtual void Accept(AstVisitor* v);                                   \
161  virtual AstNode::Type node_type() const { return AstNode::k##type; }
162
163
164enum AstPropertiesFlag {
165  kDontInline,
166  kDontOptimize,
167  kDontSelfOptimize,
168  kDontSoftInline
169};
170
171
172class AstProperties BASE_EMBEDDED {
173 public:
174  class Flags : public EnumSet<AstPropertiesFlag, int> {};
175
176  AstProperties() : node_count_(0) { }
177
178  Flags* flags() { return &flags_; }
179  int node_count() { return node_count_; }
180  void add_node_count(int count) { node_count_ += count; }
181
182 private:
183  Flags flags_;
184  int node_count_;
185};
186
187
188class AstNode: public ZoneObject {
189 public:
190#define DECLARE_TYPE_ENUM(type) k##type,
191  enum Type {
192    AST_NODE_LIST(DECLARE_TYPE_ENUM)
193    kInvalid = -1
194  };
195#undef DECLARE_TYPE_ENUM
196
197  static const int kNoNumber = -1;
198  static const int kFunctionEntryId = 2;  // Using 0 could disguise errors.
199  // This AST id identifies the point after the declarations have been
200  // visited. We need it to capture the environment effects of declarations
201  // that emit code (function declarations).
202  static const int kDeclarationsId = 3;
203
204  void* operator new(size_t size, Zone* zone) {
205    return zone->New(static_cast<int>(size));
206  }
207
208  AstNode() { }
209
210  virtual ~AstNode() { }
211
212  virtual void Accept(AstVisitor* v) = 0;
213  virtual Type node_type() const { return kInvalid; }
214
215  // Type testing & conversion functions overridden by concrete subclasses.
216#define DECLARE_NODE_FUNCTIONS(type)                  \
217  bool Is##type() { return node_type() == AstNode::k##type; }          \
218  type* As##type() { return Is##type() ? reinterpret_cast<type*>(this) : NULL; }
219  AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
220#undef DECLARE_NODE_FUNCTIONS
221
222  virtual Declaration* AsDeclaration() { return NULL; }
223  virtual Statement* AsStatement() { return NULL; }
224  virtual Expression* AsExpression() { return NULL; }
225  virtual TargetCollector* AsTargetCollector() { return NULL; }
226  virtual BreakableStatement* AsBreakableStatement() { return NULL; }
227  virtual IterationStatement* AsIterationStatement() { return NULL; }
228  virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; }
229
230 protected:
231  static int GetNextId(Isolate* isolate) {
232    return ReserveIdRange(isolate, 1);
233  }
234
235  static int ReserveIdRange(Isolate* isolate, int n) {
236    int tmp = isolate->ast_node_id();
237    isolate->set_ast_node_id(tmp + n);
238    return tmp;
239  }
240
241 private:
242  // Hidden to prevent accidental usage. It would have to load the
243  // current zone from the TLS.
244  void* operator new(size_t size);
245
246  friend class CaseClause;  // Generates AST IDs.
247};
248
249
250class Statement: public AstNode {
251 public:
252  Statement() : statement_pos_(RelocInfo::kNoPosition) {}
253
254  virtual Statement* AsStatement()  { return this; }
255
256  bool IsEmpty() { return AsEmptyStatement() != NULL; }
257
258  void set_statement_pos(int statement_pos) { statement_pos_ = statement_pos; }
259  int statement_pos() const { return statement_pos_; }
260
261 private:
262  int statement_pos_;
263};
264
265
266class SmallMapList {
267 public:
268  SmallMapList() {}
269  explicit SmallMapList(int capacity) : list_(capacity) {}
270
271  void Reserve(int capacity) { list_.Reserve(capacity); }
272  void Clear() { list_.Clear(); }
273
274  bool is_empty() const { return list_.is_empty(); }
275  int length() const { return list_.length(); }
276
277  void Add(Handle<Map> handle) {
278    list_.Add(handle.location());
279  }
280
281  Handle<Map> at(int i) const {
282    return Handle<Map>(list_.at(i));
283  }
284
285  Handle<Map> first() const { return at(0); }
286  Handle<Map> last() const { return at(length() - 1); }
287
288 private:
289  // The list stores pointers to Map*, that is Map**, so it's GC safe.
290  SmallPointerList<Map*> list_;
291
292  DISALLOW_COPY_AND_ASSIGN(SmallMapList);
293};
294
295
296class Expression: public AstNode {
297 public:
298  enum Context {
299    // Not assigned a context yet, or else will not be visited during
300    // code generation.
301    kUninitialized,
302    // Evaluated for its side effects.
303    kEffect,
304    // Evaluated for its value (and side effects).
305    kValue,
306    // Evaluated for control flow (and side effects).
307    kTest
308  };
309
310  virtual int position() const {
311    UNREACHABLE();
312    return 0;
313  }
314
315  virtual Expression* AsExpression()  { return this; }
316
317  virtual bool IsValidLeftHandSide() { return false; }
318
319  // Helpers for ToBoolean conversion.
320  virtual bool ToBooleanIsTrue() { return false; }
321  virtual bool ToBooleanIsFalse() { return false; }
322
323  // Symbols that cannot be parsed as array indices are considered property
324  // names.  We do not treat symbols that can be array indexes as property
325  // names because [] for string objects is handled only by keyed ICs.
326  virtual bool IsPropertyName() { return false; }
327
328  // True iff the result can be safely overwritten (to avoid allocation).
329  // False for operations that can return one of their operands.
330  virtual bool ResultOverwriteAllowed() { return false; }
331
332  // True iff the expression is a literal represented as a smi.
333  bool IsSmiLiteral();
334
335  // True iff the expression is a string literal.
336  bool IsStringLiteral();
337
338  // True iff the expression is the null literal.
339  bool IsNullLiteral();
340
341  // Type feedback information for assignments and properties.
342  virtual bool IsMonomorphic() {
343    UNREACHABLE();
344    return false;
345  }
346  virtual SmallMapList* GetReceiverTypes() {
347    UNREACHABLE();
348    return NULL;
349  }
350  Handle<Map> GetMonomorphicReceiverType() {
351    ASSERT(IsMonomorphic());
352    SmallMapList* types = GetReceiverTypes();
353    ASSERT(types != NULL && types->length() == 1);
354    return types->at(0);
355  }
356
357  unsigned id() const { return id_; }
358  unsigned test_id() const { return test_id_; }
359
360 protected:
361  explicit Expression(Isolate* isolate)
362      : id_(GetNextId(isolate)),
363        test_id_(GetNextId(isolate)) {}
364
365 private:
366  int id_;
367  int test_id_;
368};
369
370
371class BreakableStatement: public Statement {
372 public:
373  enum Type {
374    TARGET_FOR_ANONYMOUS,
375    TARGET_FOR_NAMED_ONLY
376  };
377
378  // The labels associated with this statement. May be NULL;
379  // if it is != NULL, guaranteed to contain at least one entry.
380  ZoneStringList* labels() const { return labels_; }
381
382  // Type testing & conversion.
383  virtual BreakableStatement* AsBreakableStatement() { return this; }
384
385  // Code generation
386  Label* break_target() { return &break_target_; }
387
388  // Testers.
389  bool is_target_for_anonymous() const { return type_ == TARGET_FOR_ANONYMOUS; }
390
391  // Bailout support.
392  int EntryId() const { return entry_id_; }
393  int ExitId() const { return exit_id_; }
394
395 protected:
396  BreakableStatement(Isolate* isolate, ZoneStringList* labels, Type type)
397      : labels_(labels),
398        type_(type),
399        entry_id_(GetNextId(isolate)),
400        exit_id_(GetNextId(isolate)) {
401    ASSERT(labels == NULL || labels->length() > 0);
402  }
403
404
405 private:
406  ZoneStringList* labels_;
407  Type type_;
408  Label break_target_;
409  int entry_id_;
410  int exit_id_;
411};
412
413
414class Block: public BreakableStatement {
415 public:
416  DECLARE_NODE_TYPE(Block)
417
418  void AddStatement(Statement* statement) { statements_.Add(statement); }
419
420  ZoneList<Statement*>* statements() { return &statements_; }
421  bool is_initializer_block() const { return is_initializer_block_; }
422
423  Scope* block_scope() const { return block_scope_; }
424  void set_block_scope(Scope* block_scope) { block_scope_ = block_scope; }
425
426 protected:
427  template<class> friend class AstNodeFactory;
428
429  Block(Isolate* isolate,
430        ZoneStringList* labels,
431        int capacity,
432        bool is_initializer_block)
433      : BreakableStatement(isolate, labels, TARGET_FOR_NAMED_ONLY),
434        statements_(capacity),
435        is_initializer_block_(is_initializer_block),
436        block_scope_(NULL) {
437  }
438
439 private:
440  ZoneList<Statement*> statements_;
441  bool is_initializer_block_;
442  Scope* block_scope_;
443};
444
445
446class Declaration: public AstNode {
447 public:
448  VariableProxy* proxy() const { return proxy_; }
449  VariableMode mode() const { return mode_; }
450  Scope* scope() const { return scope_; }
451  virtual InitializationFlag initialization() const = 0;
452  virtual bool IsInlineable() const;
453
454  virtual Declaration* AsDeclaration() { return this; }
455
456 protected:
457  Declaration(VariableProxy* proxy,
458              VariableMode mode,
459              Scope* scope)
460      : proxy_(proxy),
461        mode_(mode),
462        scope_(scope) {
463    ASSERT(mode == VAR ||
464           mode == CONST ||
465           mode == CONST_HARMONY ||
466           mode == LET);
467  }
468
469 private:
470  VariableProxy* proxy_;
471  VariableMode mode_;
472
473  // Nested scope from which the declaration originated.
474  Scope* scope_;
475};
476
477
478class VariableDeclaration: public Declaration {
479 public:
480  DECLARE_NODE_TYPE(VariableDeclaration)
481
482  virtual InitializationFlag initialization() const {
483    return mode() == VAR ? kCreatedInitialized : kNeedsInitialization;
484  }
485
486 protected:
487  template<class> friend class AstNodeFactory;
488
489  VariableDeclaration(VariableProxy* proxy,
490                      VariableMode mode,
491                      Scope* scope)
492      : Declaration(proxy, mode, scope) {
493  }
494};
495
496
497class FunctionDeclaration: public Declaration {
498 public:
499  DECLARE_NODE_TYPE(FunctionDeclaration)
500
501  FunctionLiteral* fun() const { return fun_; }
502  virtual InitializationFlag initialization() const {
503    return kCreatedInitialized;
504  }
505  virtual bool IsInlineable() const;
506
507 protected:
508  template<class> friend class AstNodeFactory;
509
510  FunctionDeclaration(VariableProxy* proxy,
511                      VariableMode mode,
512                      FunctionLiteral* fun,
513                      Scope* scope)
514      : Declaration(proxy, mode, scope),
515        fun_(fun) {
516    // At the moment there are no "const functions" in JavaScript...
517    ASSERT(mode == VAR || mode == LET);
518    ASSERT(fun != NULL);
519  }
520
521 private:
522  FunctionLiteral* fun_;
523};
524
525
526class ModuleDeclaration: public Declaration {
527 public:
528  DECLARE_NODE_TYPE(ModuleDeclaration)
529
530  Module* module() const { return module_; }
531  virtual InitializationFlag initialization() const {
532    return kCreatedInitialized;
533  }
534
535 protected:
536  template<class> friend class AstNodeFactory;
537
538  ModuleDeclaration(VariableProxy* proxy,
539                    Module* module,
540                    Scope* scope)
541      : Declaration(proxy, LET, scope),
542        module_(module) {
543  }
544
545 private:
546  Module* module_;
547};
548
549
550class ImportDeclaration: public Declaration {
551 public:
552  DECLARE_NODE_TYPE(ImportDeclaration)
553
554  Module* module() const { return module_; }
555  virtual InitializationFlag initialization() const {
556    return kCreatedInitialized;
557  }
558
559 protected:
560  template<class> friend class AstNodeFactory;
561
562  ImportDeclaration(VariableProxy* proxy,
563                    Module* module,
564                    Scope* scope)
565      : Declaration(proxy, LET, scope),
566        module_(module) {
567  }
568
569 private:
570  Module* module_;
571};
572
573
574class ExportDeclaration: public Declaration {
575 public:
576  DECLARE_NODE_TYPE(ExportDeclaration)
577
578  virtual InitializationFlag initialization() const {
579    return kCreatedInitialized;
580  }
581
582 protected:
583  template<class> friend class AstNodeFactory;
584
585  ExportDeclaration(VariableProxy* proxy,
586                    Scope* scope)
587      : Declaration(proxy, LET, scope) {
588  }
589};
590
591
592class Module: public AstNode {
593 public:
594  Interface* interface() const { return interface_; }
595
596 protected:
597  Module() : interface_(Interface::NewModule()) {}
598  explicit Module(Interface* interface) : interface_(interface) {}
599
600 private:
601  Interface* interface_;
602};
603
604
605class ModuleLiteral: public Module {
606 public:
607  DECLARE_NODE_TYPE(ModuleLiteral)
608
609  Block* body() const { return body_; }
610
611 protected:
612  template<class> friend class AstNodeFactory;
613
614  ModuleLiteral(Block* body, Interface* interface)
615      : Module(interface),
616        body_(body) {
617  }
618
619 private:
620  Block* body_;
621};
622
623
624class ModuleVariable: public Module {
625 public:
626  DECLARE_NODE_TYPE(ModuleVariable)
627
628  VariableProxy* proxy() const { return proxy_; }
629
630 protected:
631  template<class> friend class AstNodeFactory;
632
633  inline explicit ModuleVariable(VariableProxy* proxy);
634
635 private:
636  VariableProxy* proxy_;
637};
638
639
640class ModulePath: public Module {
641 public:
642  DECLARE_NODE_TYPE(ModulePath)
643
644  Module* module() const { return module_; }
645  Handle<String> name() const { return name_; }
646
647 protected:
648  template<class> friend class AstNodeFactory;
649
650  ModulePath(Module* module, Handle<String> name)
651      : module_(module),
652        name_(name) {
653  }
654
655 private:
656  Module* module_;
657  Handle<String> name_;
658};
659
660
661class ModuleUrl: public Module {
662 public:
663  DECLARE_NODE_TYPE(ModuleUrl)
664
665  Handle<String> url() const { return url_; }
666
667 protected:
668  template<class> friend class AstNodeFactory;
669
670  explicit ModuleUrl(Handle<String> url) : url_(url) {
671  }
672
673 private:
674  Handle<String> url_;
675};
676
677
678class IterationStatement: public BreakableStatement {
679 public:
680  // Type testing & conversion.
681  virtual IterationStatement* AsIterationStatement() { return this; }
682
683  Statement* body() const { return body_; }
684
685  // Bailout support.
686  int OsrEntryId() const { return osr_entry_id_; }
687  virtual int ContinueId() const = 0;
688  virtual int StackCheckId() const = 0;
689
690  // Code generation
691  Label* continue_target()  { return &continue_target_; }
692
693 protected:
694  IterationStatement(Isolate* isolate, ZoneStringList* labels)
695      : BreakableStatement(isolate, labels, TARGET_FOR_ANONYMOUS),
696        body_(NULL),
697        osr_entry_id_(GetNextId(isolate)) {
698  }
699
700  void Initialize(Statement* body) {
701    body_ = body;
702  }
703
704 private:
705  Statement* body_;
706  Label continue_target_;
707  int osr_entry_id_;
708};
709
710
711class DoWhileStatement: public IterationStatement {
712 public:
713  DECLARE_NODE_TYPE(DoWhileStatement)
714
715  void Initialize(Expression* cond, Statement* body) {
716    IterationStatement::Initialize(body);
717    cond_ = cond;
718  }
719
720  Expression* cond() const { return cond_; }
721
722  // Position where condition expression starts. We need it to make
723  // the loop's condition a breakable location.
724  int condition_position() { return condition_position_; }
725  void set_condition_position(int pos) { condition_position_ = pos; }
726
727  // Bailout support.
728  virtual int ContinueId() const { return continue_id_; }
729  virtual int StackCheckId() const { return back_edge_id_; }
730  int BackEdgeId() const { return back_edge_id_; }
731
732 protected:
733  template<class> friend class AstNodeFactory;
734
735  DoWhileStatement(Isolate* isolate, ZoneStringList* labels)
736      : IterationStatement(isolate, labels),
737        cond_(NULL),
738        condition_position_(-1),
739        continue_id_(GetNextId(isolate)),
740        back_edge_id_(GetNextId(isolate)) {
741  }
742
743 private:
744  Expression* cond_;
745  int condition_position_;
746  int continue_id_;
747  int back_edge_id_;
748};
749
750
751class WhileStatement: public IterationStatement {
752 public:
753  DECLARE_NODE_TYPE(WhileStatement)
754
755  void Initialize(Expression* cond, Statement* body) {
756    IterationStatement::Initialize(body);
757    cond_ = cond;
758  }
759
760  Expression* cond() const { return cond_; }
761  bool may_have_function_literal() const {
762    return may_have_function_literal_;
763  }
764  void set_may_have_function_literal(bool value) {
765    may_have_function_literal_ = value;
766  }
767
768  // Bailout support.
769  virtual int ContinueId() const { return EntryId(); }
770  virtual int StackCheckId() const { return body_id_; }
771  int BodyId() const { return body_id_; }
772
773 protected:
774  template<class> friend class AstNodeFactory;
775
776  WhileStatement(Isolate* isolate, ZoneStringList* labels)
777      : IterationStatement(isolate, labels),
778        cond_(NULL),
779        may_have_function_literal_(true),
780        body_id_(GetNextId(isolate)) {
781  }
782
783 private:
784  Expression* cond_;
785  // True if there is a function literal subexpression in the condition.
786  bool may_have_function_literal_;
787  int body_id_;
788};
789
790
791class ForStatement: public IterationStatement {
792 public:
793  DECLARE_NODE_TYPE(ForStatement)
794
795  void Initialize(Statement* init,
796                  Expression* cond,
797                  Statement* next,
798                  Statement* body) {
799    IterationStatement::Initialize(body);
800    init_ = init;
801    cond_ = cond;
802    next_ = next;
803  }
804
805  Statement* init() const { return init_; }
806  Expression* cond() const { return cond_; }
807  Statement* next() const { return next_; }
808
809  bool may_have_function_literal() const {
810    return may_have_function_literal_;
811  }
812  void set_may_have_function_literal(bool value) {
813    may_have_function_literal_ = value;
814  }
815
816  // Bailout support.
817  virtual int ContinueId() const { return continue_id_; }
818  virtual int StackCheckId() const { return body_id_; }
819  int BodyId() const { return body_id_; }
820
821  bool is_fast_smi_loop() { return loop_variable_ != NULL; }
822  Variable* loop_variable() { return loop_variable_; }
823  void set_loop_variable(Variable* var) { loop_variable_ = var; }
824
825 protected:
826  template<class> friend class AstNodeFactory;
827
828  ForStatement(Isolate* isolate, ZoneStringList* labels)
829      : IterationStatement(isolate, labels),
830        init_(NULL),
831        cond_(NULL),
832        next_(NULL),
833        may_have_function_literal_(true),
834        loop_variable_(NULL),
835        continue_id_(GetNextId(isolate)),
836        body_id_(GetNextId(isolate)) {
837  }
838
839 private:
840  Statement* init_;
841  Expression* cond_;
842  Statement* next_;
843  // True if there is a function literal subexpression in the condition.
844  bool may_have_function_literal_;
845  Variable* loop_variable_;
846  int continue_id_;
847  int body_id_;
848};
849
850
851class ForInStatement: public IterationStatement {
852 public:
853  DECLARE_NODE_TYPE(ForInStatement)
854
855  void Initialize(Expression* each, Expression* enumerable, Statement* body) {
856    IterationStatement::Initialize(body);
857    each_ = each;
858    enumerable_ = enumerable;
859  }
860
861  Expression* each() const { return each_; }
862  Expression* enumerable() const { return enumerable_; }
863
864  virtual int ContinueId() const { return EntryId(); }
865  virtual int StackCheckId() const { return body_id_; }
866  int BodyId() const { return body_id_; }
867  int PrepareId() const { return prepare_id_; }
868
869 protected:
870  template<class> friend class AstNodeFactory;
871
872  ForInStatement(Isolate* isolate, ZoneStringList* labels)
873      : IterationStatement(isolate, labels),
874        each_(NULL),
875        enumerable_(NULL),
876        body_id_(GetNextId(isolate)),
877        prepare_id_(GetNextId(isolate)) {
878  }
879
880 private:
881  Expression* each_;
882  Expression* enumerable_;
883  int body_id_;
884  int prepare_id_;
885};
886
887
888class ExpressionStatement: public Statement {
889 public:
890  DECLARE_NODE_TYPE(ExpressionStatement)
891
892  void set_expression(Expression* e) { expression_ = e; }
893  Expression* expression() const { return expression_; }
894
895 protected:
896  template<class> friend class AstNodeFactory;
897
898  explicit ExpressionStatement(Expression* expression)
899      : expression_(expression) { }
900
901 private:
902  Expression* expression_;
903};
904
905
906class ContinueStatement: public Statement {
907 public:
908  DECLARE_NODE_TYPE(ContinueStatement)
909
910  IterationStatement* target() const { return target_; }
911
912 protected:
913  template<class> friend class AstNodeFactory;
914
915  explicit ContinueStatement(IterationStatement* target)
916      : target_(target) { }
917
918 private:
919  IterationStatement* target_;
920};
921
922
923class BreakStatement: public Statement {
924 public:
925  DECLARE_NODE_TYPE(BreakStatement)
926
927  BreakableStatement* target() const { return target_; }
928
929 protected:
930  template<class> friend class AstNodeFactory;
931
932  explicit BreakStatement(BreakableStatement* target)
933      : target_(target) { }
934
935 private:
936  BreakableStatement* target_;
937};
938
939
940class ReturnStatement: public Statement {
941 public:
942  DECLARE_NODE_TYPE(ReturnStatement)
943
944  Expression* expression() const { return expression_; }
945
946 protected:
947  template<class> friend class AstNodeFactory;
948
949  explicit ReturnStatement(Expression* expression)
950      : expression_(expression) { }
951
952 private:
953  Expression* expression_;
954};
955
956
957class WithStatement: public Statement {
958 public:
959  DECLARE_NODE_TYPE(WithStatement)
960
961  Expression* expression() const { return expression_; }
962  Statement* statement() const { return statement_; }
963
964 protected:
965  template<class> friend class AstNodeFactory;
966
967  WithStatement(Expression* expression, Statement* statement)
968      : expression_(expression),
969        statement_(statement) { }
970
971 private:
972  Expression* expression_;
973  Statement* statement_;
974};
975
976
977class CaseClause: public ZoneObject {
978 public:
979  CaseClause(Isolate* isolate,
980             Expression* label,
981             ZoneList<Statement*>* statements,
982             int pos);
983
984  bool is_default() const { return label_ == NULL; }
985  Expression* label() const {
986    CHECK(!is_default());
987    return label_;
988  }
989  Label* body_target() { return &body_target_; }
990  ZoneList<Statement*>* statements() const { return statements_; }
991
992  int position() const { return position_; }
993  void set_position(int pos) { position_ = pos; }
994
995  int EntryId() { return entry_id_; }
996  int CompareId() { return compare_id_; }
997
998  // Type feedback information.
999  void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1000  bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
1001  bool IsSymbolCompare() { return compare_type_ == SYMBOL_ONLY; }
1002  bool IsStringCompare() { return compare_type_ == STRING_ONLY; }
1003  bool IsObjectCompare() { return compare_type_ == OBJECT_ONLY; }
1004
1005 private:
1006  Expression* label_;
1007  Label body_target_;
1008  ZoneList<Statement*>* statements_;
1009  int position_;
1010  enum CompareTypeFeedback {
1011    NONE,
1012    SMI_ONLY,
1013    SYMBOL_ONLY,
1014    STRING_ONLY,
1015    OBJECT_ONLY
1016  };
1017  CompareTypeFeedback compare_type_;
1018  int compare_id_;
1019  int entry_id_;
1020};
1021
1022
1023class SwitchStatement: public BreakableStatement {
1024 public:
1025  DECLARE_NODE_TYPE(SwitchStatement)
1026
1027  void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) {
1028    tag_ = tag;
1029    cases_ = cases;
1030  }
1031
1032  Expression* tag() const { return tag_; }
1033  ZoneList<CaseClause*>* cases() const { return cases_; }
1034
1035 protected:
1036  template<class> friend class AstNodeFactory;
1037
1038  SwitchStatement(Isolate* isolate, ZoneStringList* labels)
1039      : BreakableStatement(isolate, labels, TARGET_FOR_ANONYMOUS),
1040        tag_(NULL),
1041        cases_(NULL) { }
1042
1043 private:
1044  Expression* tag_;
1045  ZoneList<CaseClause*>* cases_;
1046};
1047
1048
1049// If-statements always have non-null references to their then- and
1050// else-parts. When parsing if-statements with no explicit else-part,
1051// the parser implicitly creates an empty statement. Use the
1052// HasThenStatement() and HasElseStatement() functions to check if a
1053// given if-statement has a then- or an else-part containing code.
1054class IfStatement: public Statement {
1055 public:
1056  DECLARE_NODE_TYPE(IfStatement)
1057
1058  bool HasThenStatement() const { return !then_statement()->IsEmpty(); }
1059  bool HasElseStatement() const { return !else_statement()->IsEmpty(); }
1060
1061  Expression* condition() const { return condition_; }
1062  Statement* then_statement() const { return then_statement_; }
1063  Statement* else_statement() const { return else_statement_; }
1064
1065  int IfId() const { return if_id_; }
1066  int ThenId() const { return then_id_; }
1067  int ElseId() const { return else_id_; }
1068
1069 protected:
1070  template<class> friend class AstNodeFactory;
1071
1072  IfStatement(Isolate* isolate,
1073              Expression* condition,
1074              Statement* then_statement,
1075              Statement* else_statement)
1076      : condition_(condition),
1077        then_statement_(then_statement),
1078        else_statement_(else_statement),
1079        if_id_(GetNextId(isolate)),
1080        then_id_(GetNextId(isolate)),
1081        else_id_(GetNextId(isolate)) {
1082  }
1083
1084 private:
1085  Expression* condition_;
1086  Statement* then_statement_;
1087  Statement* else_statement_;
1088  int if_id_;
1089  int then_id_;
1090  int else_id_;
1091};
1092
1093
1094// NOTE: TargetCollectors are represented as nodes to fit in the target
1095// stack in the compiler; this should probably be reworked.
1096class TargetCollector: public AstNode {
1097 public:
1098  TargetCollector() : targets_(0) { }
1099
1100  // Adds a jump target to the collector. The collector stores a pointer not
1101  // a copy of the target to make binding work, so make sure not to pass in
1102  // references to something on the stack.
1103  void AddTarget(Label* target);
1104
1105  // Virtual behaviour. TargetCollectors are never part of the AST.
1106  virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
1107  virtual TargetCollector* AsTargetCollector() { return this; }
1108
1109  ZoneList<Label*>* targets() { return &targets_; }
1110
1111 private:
1112  ZoneList<Label*> targets_;
1113};
1114
1115
1116class TryStatement: public Statement {
1117 public:
1118  void set_escaping_targets(ZoneList<Label*>* targets) {
1119    escaping_targets_ = targets;
1120  }
1121
1122  int index() const { return index_; }
1123  Block* try_block() const { return try_block_; }
1124  ZoneList<Label*>* escaping_targets() const { return escaping_targets_; }
1125
1126 protected:
1127  TryStatement(int index, Block* try_block)
1128      : index_(index),
1129        try_block_(try_block),
1130        escaping_targets_(NULL) { }
1131
1132 private:
1133  // Unique (per-function) index of this handler.  This is not an AST ID.
1134  int index_;
1135
1136  Block* try_block_;
1137  ZoneList<Label*>* escaping_targets_;
1138};
1139
1140
1141class TryCatchStatement: public TryStatement {
1142 public:
1143  DECLARE_NODE_TYPE(TryCatchStatement)
1144
1145  Scope* scope() { return scope_; }
1146  Variable* variable() { return variable_; }
1147  Block* catch_block() const { return catch_block_; }
1148
1149 protected:
1150  template<class> friend class AstNodeFactory;
1151
1152  TryCatchStatement(int index,
1153                    Block* try_block,
1154                    Scope* scope,
1155                    Variable* variable,
1156                    Block* catch_block)
1157      : TryStatement(index, try_block),
1158        scope_(scope),
1159        variable_(variable),
1160        catch_block_(catch_block) {
1161  }
1162
1163 private:
1164  Scope* scope_;
1165  Variable* variable_;
1166  Block* catch_block_;
1167};
1168
1169
1170class TryFinallyStatement: public TryStatement {
1171 public:
1172  DECLARE_NODE_TYPE(TryFinallyStatement)
1173
1174  Block* finally_block() const { return finally_block_; }
1175
1176 protected:
1177  template<class> friend class AstNodeFactory;
1178
1179  TryFinallyStatement(int index, Block* try_block, Block* finally_block)
1180      : TryStatement(index, try_block),
1181        finally_block_(finally_block) { }
1182
1183 private:
1184  Block* finally_block_;
1185};
1186
1187
1188class DebuggerStatement: public Statement {
1189 public:
1190  DECLARE_NODE_TYPE(DebuggerStatement)
1191
1192 protected:
1193  template<class> friend class AstNodeFactory;
1194
1195  DebuggerStatement() {}
1196};
1197
1198
1199class EmptyStatement: public Statement {
1200 public:
1201  DECLARE_NODE_TYPE(EmptyStatement)
1202
1203 protected:
1204  template<class> friend class AstNodeFactory;
1205
1206  EmptyStatement() {}
1207};
1208
1209
1210class Literal: public Expression {
1211 public:
1212  DECLARE_NODE_TYPE(Literal)
1213
1214  virtual bool IsPropertyName() {
1215    if (handle_->IsSymbol()) {
1216      uint32_t ignored;
1217      return !String::cast(*handle_)->AsArrayIndex(&ignored);
1218    }
1219    return false;
1220  }
1221
1222  Handle<String> AsPropertyName() {
1223    ASSERT(IsPropertyName());
1224    return Handle<String>::cast(handle_);
1225  }
1226
1227  virtual bool ToBooleanIsTrue() { return handle_->ToBoolean()->IsTrue(); }
1228  virtual bool ToBooleanIsFalse() { return handle_->ToBoolean()->IsFalse(); }
1229
1230  // Identity testers.
1231  bool IsNull() const {
1232    ASSERT(!handle_.is_null());
1233    return handle_->IsNull();
1234  }
1235  bool IsTrue() const {
1236    ASSERT(!handle_.is_null());
1237    return handle_->IsTrue();
1238  }
1239  bool IsFalse() const {
1240    ASSERT(!handle_.is_null());
1241    return handle_->IsFalse();
1242  }
1243
1244  Handle<Object> handle() const { return handle_; }
1245
1246  // Support for using Literal as a HashMap key. NOTE: Currently, this works
1247  // only for string and number literals!
1248  uint32_t Hash() { return ToString()->Hash(); }
1249
1250  static bool Match(void* literal1, void* literal2) {
1251    Handle<String> s1 = static_cast<Literal*>(literal1)->ToString();
1252    Handle<String> s2 = static_cast<Literal*>(literal2)->ToString();
1253    return s1->Equals(*s2);
1254  }
1255
1256 protected:
1257  template<class> friend class AstNodeFactory;
1258
1259  Literal(Isolate* isolate, Handle<Object> handle)
1260      : Expression(isolate),
1261        handle_(handle) { }
1262
1263 private:
1264  Handle<String> ToString();
1265
1266  Handle<Object> handle_;
1267};
1268
1269
1270// Base class for literals that needs space in the corresponding JSFunction.
1271class MaterializedLiteral: public Expression {
1272 public:
1273  virtual MaterializedLiteral* AsMaterializedLiteral() { return this; }
1274
1275  int literal_index() { return literal_index_; }
1276
1277  // A materialized literal is simple if the values consist of only
1278  // constants and simple object and array literals.
1279  bool is_simple() const { return is_simple_; }
1280
1281  int depth() const { return depth_; }
1282
1283 protected:
1284  MaterializedLiteral(Isolate* isolate,
1285                      int literal_index,
1286                      bool is_simple,
1287                      int depth)
1288      : Expression(isolate),
1289        literal_index_(literal_index),
1290        is_simple_(is_simple),
1291        depth_(depth) {}
1292
1293 private:
1294  int literal_index_;
1295  bool is_simple_;
1296  int depth_;
1297};
1298
1299
1300// An object literal has a boilerplate object that is used
1301// for minimizing the work when constructing it at runtime.
1302class ObjectLiteral: public MaterializedLiteral {
1303 public:
1304  // Property is used for passing information
1305  // about an object literal's properties from the parser
1306  // to the code generator.
1307  class Property: public ZoneObject {
1308   public:
1309    enum Kind {
1310      CONSTANT,              // Property with constant value (compile time).
1311      COMPUTED,              // Property with computed value (execution time).
1312      MATERIALIZED_LITERAL,  // Property value is a materialized literal.
1313      GETTER, SETTER,        // Property is an accessor function.
1314      PROTOTYPE              // Property is __proto__.
1315    };
1316
1317    Property(Literal* key, Expression* value, Isolate* isolate);
1318
1319    Literal* key() { return key_; }
1320    Expression* value() { return value_; }
1321    Kind kind() { return kind_; }
1322
1323    // Type feedback information.
1324    void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1325    bool IsMonomorphic() { return !receiver_type_.is_null(); }
1326    Handle<Map> GetReceiverType() { return receiver_type_; }
1327
1328    bool IsCompileTimeValue();
1329
1330    void set_emit_store(bool emit_store);
1331    bool emit_store();
1332
1333   protected:
1334    template<class> friend class AstNodeFactory;
1335
1336    Property(bool is_getter, FunctionLiteral* value);
1337    void set_key(Literal* key) { key_ = key; }
1338
1339   private:
1340    Literal* key_;
1341    Expression* value_;
1342    Kind kind_;
1343    bool emit_store_;
1344    Handle<Map> receiver_type_;
1345  };
1346
1347  DECLARE_NODE_TYPE(ObjectLiteral)
1348
1349  Handle<FixedArray> constant_properties() const {
1350    return constant_properties_;
1351  }
1352  ZoneList<Property*>* properties() const { return properties_; }
1353
1354  bool fast_elements() const { return fast_elements_; }
1355
1356  bool has_function() { return has_function_; }
1357
1358  // Mark all computed expressions that are bound to a key that
1359  // is shadowed by a later occurrence of the same key. For the
1360  // marked expressions, no store code is emitted.
1361  void CalculateEmitStore();
1362
1363  enum Flags {
1364    kNoFlags = 0,
1365    kFastElements = 1,
1366    kHasFunction = 1 << 1
1367  };
1368
1369  struct Accessors: public ZoneObject {
1370    Accessors() : getter(NULL), setter(NULL) { }
1371    Expression* getter;
1372    Expression* setter;
1373  };
1374
1375 protected:
1376  template<class> friend class AstNodeFactory;
1377
1378  ObjectLiteral(Isolate* isolate,
1379                Handle<FixedArray> constant_properties,
1380                ZoneList<Property*>* properties,
1381                int literal_index,
1382                bool is_simple,
1383                bool fast_elements,
1384                int depth,
1385                bool has_function)
1386      : MaterializedLiteral(isolate, literal_index, is_simple, depth),
1387        constant_properties_(constant_properties),
1388        properties_(properties),
1389        fast_elements_(fast_elements),
1390        has_function_(has_function) {}
1391
1392 private:
1393  Handle<FixedArray> constant_properties_;
1394  ZoneList<Property*>* properties_;
1395  bool fast_elements_;
1396  bool has_function_;
1397};
1398
1399
1400// Node for capturing a regexp literal.
1401class RegExpLiteral: public MaterializedLiteral {
1402 public:
1403  DECLARE_NODE_TYPE(RegExpLiteral)
1404
1405  Handle<String> pattern() const { return pattern_; }
1406  Handle<String> flags() const { return flags_; }
1407
1408 protected:
1409  template<class> friend class AstNodeFactory;
1410
1411  RegExpLiteral(Isolate* isolate,
1412                Handle<String> pattern,
1413                Handle<String> flags,
1414                int literal_index)
1415      : MaterializedLiteral(isolate, literal_index, false, 1),
1416        pattern_(pattern),
1417        flags_(flags) {}
1418
1419 private:
1420  Handle<String> pattern_;
1421  Handle<String> flags_;
1422};
1423
1424// An array literal has a literals object that is used
1425// for minimizing the work when constructing it at runtime.
1426class ArrayLiteral: public MaterializedLiteral {
1427 public:
1428  DECLARE_NODE_TYPE(ArrayLiteral)
1429
1430  Handle<FixedArray> constant_elements() const { return constant_elements_; }
1431  ZoneList<Expression*>* values() const { return values_; }
1432
1433  // Return an AST id for an element that is used in simulate instructions.
1434  int GetIdForElement(int i) { return first_element_id_ + i; }
1435
1436 protected:
1437  template<class> friend class AstNodeFactory;
1438
1439  ArrayLiteral(Isolate* isolate,
1440               Handle<FixedArray> constant_elements,
1441               ZoneList<Expression*>* values,
1442               int literal_index,
1443               bool is_simple,
1444               int depth)
1445      : MaterializedLiteral(isolate, literal_index, is_simple, depth),
1446        constant_elements_(constant_elements),
1447        values_(values),
1448        first_element_id_(ReserveIdRange(isolate, values->length())) {}
1449
1450 private:
1451  Handle<FixedArray> constant_elements_;
1452  ZoneList<Expression*>* values_;
1453  int first_element_id_;
1454};
1455
1456
1457class VariableProxy: public Expression {
1458 public:
1459  DECLARE_NODE_TYPE(VariableProxy)
1460
1461  virtual bool IsValidLeftHandSide() {
1462    return var_ == NULL ? true : var_->IsValidLeftHandSide();
1463  }
1464
1465  bool IsVariable(Handle<String> n) {
1466    return !is_this() && name().is_identical_to(n);
1467  }
1468
1469  bool IsArguments() { return var_ != NULL && var_->is_arguments(); }
1470
1471  bool IsLValue() {
1472    return is_lvalue_;
1473  }
1474
1475  Handle<String> name() const { return name_; }
1476  Variable* var() const { return var_; }
1477  bool is_this() const { return is_this_; }
1478  int position() const { return position_; }
1479  Interface* interface() const { return interface_; }
1480
1481
1482  void MarkAsTrivial() { is_trivial_ = true; }
1483  void MarkAsLValue() { is_lvalue_ = true; }
1484
1485  // Bind this proxy to the variable var.
1486  void BindTo(Variable* var);
1487
1488 protected:
1489  template<class> friend class AstNodeFactory;
1490
1491  VariableProxy(Isolate* isolate, Variable* var);
1492
1493  VariableProxy(Isolate* isolate,
1494                Handle<String> name,
1495                bool is_this,
1496                int position,
1497                Interface* interface);
1498
1499  Handle<String> name_;
1500  Variable* var_;  // resolved variable, or NULL
1501  bool is_this_;
1502  bool is_trivial_;
1503  // True if this variable proxy is being used in an assignment
1504  // or with a increment/decrement operator.
1505  bool is_lvalue_;
1506  int position_;
1507  Interface* interface_;
1508};
1509
1510
1511class Property: public Expression {
1512 public:
1513  DECLARE_NODE_TYPE(Property)
1514
1515  virtual bool IsValidLeftHandSide() { return true; }
1516
1517  Expression* obj() const { return obj_; }
1518  Expression* key() const { return key_; }
1519  virtual int position() const { return pos_; }
1520
1521  bool IsStringLength() const { return is_string_length_; }
1522  bool IsStringAccess() const { return is_string_access_; }
1523  bool IsFunctionPrototype() const { return is_function_prototype_; }
1524
1525  // Type feedback information.
1526  void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1527  virtual bool IsMonomorphic() { return is_monomorphic_; }
1528  virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
1529  bool IsArrayLength() { return is_array_length_; }
1530  bool IsUninitialized() { return is_uninitialized_; }
1531
1532 protected:
1533  template<class> friend class AstNodeFactory;
1534
1535  Property(Isolate* isolate,
1536           Expression* obj,
1537           Expression* key,
1538           int pos)
1539      : Expression(isolate),
1540        obj_(obj),
1541        key_(key),
1542        pos_(pos),
1543        is_monomorphic_(false),
1544        is_uninitialized_(false),
1545        is_array_length_(false),
1546        is_string_length_(false),
1547        is_string_access_(false),
1548        is_function_prototype_(false) { }
1549
1550 private:
1551  Expression* obj_;
1552  Expression* key_;
1553  int pos_;
1554
1555  SmallMapList receiver_types_;
1556  bool is_monomorphic_ : 1;
1557  bool is_uninitialized_ : 1;
1558  bool is_array_length_ : 1;
1559  bool is_string_length_ : 1;
1560  bool is_string_access_ : 1;
1561  bool is_function_prototype_ : 1;
1562};
1563
1564
1565class Call: public Expression {
1566 public:
1567  DECLARE_NODE_TYPE(Call)
1568
1569  Expression* expression() const { return expression_; }
1570  ZoneList<Expression*>* arguments() const { return arguments_; }
1571  virtual int position() const { return pos_; }
1572
1573  void RecordTypeFeedback(TypeFeedbackOracle* oracle,
1574                          CallKind call_kind);
1575  virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
1576  virtual bool IsMonomorphic() { return is_monomorphic_; }
1577  CheckType check_type() const { return check_type_; }
1578  Handle<JSFunction> target() { return target_; }
1579  Handle<JSObject> holder() { return holder_; }
1580  Handle<JSGlobalPropertyCell> cell() { return cell_; }
1581
1582  bool ComputeTarget(Handle<Map> type, Handle<String> name);
1583  bool ComputeGlobalTarget(Handle<GlobalObject> global, LookupResult* lookup);
1584
1585  // Bailout support.
1586  int ReturnId() const { return return_id_; }
1587
1588#ifdef DEBUG
1589  // Used to assert that the FullCodeGenerator records the return site.
1590  bool return_is_recorded_;
1591#endif
1592
1593 protected:
1594  template<class> friend class AstNodeFactory;
1595
1596  Call(Isolate* isolate,
1597       Expression* expression,
1598       ZoneList<Expression*>* arguments,
1599       int pos)
1600      : Expression(isolate),
1601        expression_(expression),
1602        arguments_(arguments),
1603        pos_(pos),
1604        is_monomorphic_(false),
1605        check_type_(RECEIVER_MAP_CHECK),
1606        return_id_(GetNextId(isolate)) { }
1607
1608 private:
1609  Expression* expression_;
1610  ZoneList<Expression*>* arguments_;
1611  int pos_;
1612
1613  bool is_monomorphic_;
1614  CheckType check_type_;
1615  SmallMapList receiver_types_;
1616  Handle<JSFunction> target_;
1617  Handle<JSObject> holder_;
1618  Handle<JSGlobalPropertyCell> cell_;
1619
1620  int return_id_;
1621};
1622
1623
1624class CallNew: public Expression {
1625 public:
1626  DECLARE_NODE_TYPE(CallNew)
1627
1628  Expression* expression() const { return expression_; }
1629  ZoneList<Expression*>* arguments() const { return arguments_; }
1630  virtual int position() const { return pos_; }
1631
1632  void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1633  virtual bool IsMonomorphic() { return is_monomorphic_; }
1634  Handle<JSFunction> target() { return target_; }
1635
1636  // Bailout support.
1637  int ReturnId() const { return return_id_; }
1638
1639 protected:
1640  template<class> friend class AstNodeFactory;
1641
1642  CallNew(Isolate* isolate,
1643          Expression* expression,
1644          ZoneList<Expression*>* arguments,
1645          int pos)
1646      : Expression(isolate),
1647        expression_(expression),
1648        arguments_(arguments),
1649        pos_(pos),
1650        is_monomorphic_(false),
1651        return_id_(GetNextId(isolate)) { }
1652
1653 private:
1654  Expression* expression_;
1655  ZoneList<Expression*>* arguments_;
1656  int pos_;
1657
1658  bool is_monomorphic_;
1659  Handle<JSFunction> target_;
1660
1661  int return_id_;
1662};
1663
1664
1665// The CallRuntime class does not represent any official JavaScript
1666// language construct. Instead it is used to call a C or JS function
1667// with a set of arguments. This is used from the builtins that are
1668// implemented in JavaScript (see "v8natives.js").
1669class CallRuntime: public Expression {
1670 public:
1671  DECLARE_NODE_TYPE(CallRuntime)
1672
1673  Handle<String> name() const { return name_; }
1674  const Runtime::Function* function() const { return function_; }
1675  ZoneList<Expression*>* arguments() const { return arguments_; }
1676  bool is_jsruntime() const { return function_ == NULL; }
1677
1678 protected:
1679  template<class> friend class AstNodeFactory;
1680
1681  CallRuntime(Isolate* isolate,
1682              Handle<String> name,
1683              const Runtime::Function* function,
1684              ZoneList<Expression*>* arguments)
1685      : Expression(isolate),
1686        name_(name),
1687        function_(function),
1688        arguments_(arguments) { }
1689
1690 private:
1691  Handle<String> name_;
1692  const Runtime::Function* function_;
1693  ZoneList<Expression*>* arguments_;
1694};
1695
1696
1697class UnaryOperation: public Expression {
1698 public:
1699  DECLARE_NODE_TYPE(UnaryOperation)
1700
1701  virtual bool ResultOverwriteAllowed();
1702
1703  Token::Value op() const { return op_; }
1704  Expression* expression() const { return expression_; }
1705  virtual int position() const { return pos_; }
1706
1707  int MaterializeTrueId() { return materialize_true_id_; }
1708  int MaterializeFalseId() { return materialize_false_id_; }
1709
1710 protected:
1711  template<class> friend class AstNodeFactory;
1712
1713  UnaryOperation(Isolate* isolate,
1714                 Token::Value op,
1715                 Expression* expression,
1716                 int pos)
1717      : Expression(isolate),
1718        op_(op),
1719        expression_(expression),
1720        pos_(pos),
1721        materialize_true_id_(AstNode::kNoNumber),
1722        materialize_false_id_(AstNode::kNoNumber) {
1723    ASSERT(Token::IsUnaryOp(op));
1724    if (op == Token::NOT) {
1725      materialize_true_id_ = GetNextId(isolate);
1726      materialize_false_id_ = GetNextId(isolate);
1727    }
1728  }
1729
1730 private:
1731  Token::Value op_;
1732  Expression* expression_;
1733  int pos_;
1734
1735  // For unary not (Token::NOT), the AST ids where true and false will
1736  // actually be materialized, respectively.
1737  int materialize_true_id_;
1738  int materialize_false_id_;
1739};
1740
1741
1742class BinaryOperation: public Expression {
1743 public:
1744  DECLARE_NODE_TYPE(BinaryOperation)
1745
1746  virtual bool ResultOverwriteAllowed();
1747
1748  Token::Value op() const { return op_; }
1749  Expression* left() const { return left_; }
1750  Expression* right() const { return right_; }
1751  virtual int position() const { return pos_; }
1752
1753  // Bailout support.
1754  int RightId() const { return right_id_; }
1755
1756 protected:
1757  template<class> friend class AstNodeFactory;
1758
1759  BinaryOperation(Isolate* isolate,
1760                  Token::Value op,
1761                  Expression* left,
1762                  Expression* right,
1763                  int pos)
1764      : Expression(isolate), op_(op), left_(left), right_(right), pos_(pos) {
1765    ASSERT(Token::IsBinaryOp(op));
1766    right_id_ = (op == Token::AND || op == Token::OR)
1767        ? GetNextId(isolate)
1768        : AstNode::kNoNumber;
1769  }
1770
1771 private:
1772  Token::Value op_;
1773  Expression* left_;
1774  Expression* right_;
1775  int pos_;
1776  // The short-circuit logical operations have an AST ID for their
1777  // right-hand subexpression.
1778  int right_id_;
1779};
1780
1781
1782class CountOperation: public Expression {
1783 public:
1784  DECLARE_NODE_TYPE(CountOperation)
1785
1786  bool is_prefix() const { return is_prefix_; }
1787  bool is_postfix() const { return !is_prefix_; }
1788
1789  Token::Value op() const { return op_; }
1790  Token::Value binary_op() {
1791    return (op() == Token::INC) ? Token::ADD : Token::SUB;
1792  }
1793
1794  Expression* expression() const { return expression_; }
1795  virtual int position() const { return pos_; }
1796
1797  virtual void MarkAsStatement() { is_prefix_ = true; }
1798
1799  void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1800  virtual bool IsMonomorphic() { return is_monomorphic_; }
1801  virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
1802
1803  // Bailout support.
1804  int AssignmentId() const { return assignment_id_; }
1805  int CountId() const { return count_id_; }
1806
1807 protected:
1808  template<class> friend class AstNodeFactory;
1809
1810  CountOperation(Isolate* isolate,
1811                 Token::Value op,
1812                 bool is_prefix,
1813                 Expression* expr,
1814                 int pos)
1815      : Expression(isolate),
1816        op_(op),
1817        is_prefix_(is_prefix),
1818        expression_(expr),
1819        pos_(pos),
1820        assignment_id_(GetNextId(isolate)),
1821        count_id_(GetNextId(isolate)) {}
1822
1823 private:
1824  Token::Value op_;
1825  bool is_prefix_;
1826  bool is_monomorphic_;
1827  Expression* expression_;
1828  int pos_;
1829  int assignment_id_;
1830  int count_id_;
1831  SmallMapList receiver_types_;
1832};
1833
1834
1835class CompareOperation: public Expression {
1836 public:
1837  DECLARE_NODE_TYPE(CompareOperation)
1838
1839  Token::Value op() const { return op_; }
1840  Expression* left() const { return left_; }
1841  Expression* right() const { return right_; }
1842  virtual int position() const { return pos_; }
1843
1844  // Type feedback information.
1845  void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1846  bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
1847  bool IsObjectCompare() { return compare_type_ == OBJECT_ONLY; }
1848
1849  // Match special cases.
1850  bool IsLiteralCompareTypeof(Expression** expr, Handle<String>* check);
1851  bool IsLiteralCompareUndefined(Expression** expr);
1852  bool IsLiteralCompareNull(Expression** expr);
1853
1854 protected:
1855  template<class> friend class AstNodeFactory;
1856
1857  CompareOperation(Isolate* isolate,
1858                   Token::Value op,
1859                   Expression* left,
1860                   Expression* right,
1861                   int pos)
1862      : Expression(isolate),
1863        op_(op),
1864        left_(left),
1865        right_(right),
1866        pos_(pos),
1867        compare_type_(NONE) {
1868    ASSERT(Token::IsCompareOp(op));
1869  }
1870
1871 private:
1872  Token::Value op_;
1873  Expression* left_;
1874  Expression* right_;
1875  int pos_;
1876
1877  enum CompareTypeFeedback { NONE, SMI_ONLY, OBJECT_ONLY };
1878  CompareTypeFeedback compare_type_;
1879};
1880
1881
1882class Conditional: public Expression {
1883 public:
1884  DECLARE_NODE_TYPE(Conditional)
1885
1886  Expression* condition() const { return condition_; }
1887  Expression* then_expression() const { return then_expression_; }
1888  Expression* else_expression() const { return else_expression_; }
1889
1890  int then_expression_position() const { return then_expression_position_; }
1891  int else_expression_position() const { return else_expression_position_; }
1892
1893  int ThenId() const { return then_id_; }
1894  int ElseId() const { return else_id_; }
1895
1896 protected:
1897  template<class> friend class AstNodeFactory;
1898
1899  Conditional(Isolate* isolate,
1900              Expression* condition,
1901              Expression* then_expression,
1902              Expression* else_expression,
1903              int then_expression_position,
1904              int else_expression_position)
1905      : Expression(isolate),
1906        condition_(condition),
1907        then_expression_(then_expression),
1908        else_expression_(else_expression),
1909        then_expression_position_(then_expression_position),
1910        else_expression_position_(else_expression_position),
1911        then_id_(GetNextId(isolate)),
1912        else_id_(GetNextId(isolate)) { }
1913
1914 private:
1915  Expression* condition_;
1916  Expression* then_expression_;
1917  Expression* else_expression_;
1918  int then_expression_position_;
1919  int else_expression_position_;
1920  int then_id_;
1921  int else_id_;
1922};
1923
1924
1925class Assignment: public Expression {
1926 public:
1927  DECLARE_NODE_TYPE(Assignment)
1928
1929  Assignment* AsSimpleAssignment() { return !is_compound() ? this : NULL; }
1930
1931  Token::Value binary_op() const;
1932
1933  Token::Value op() const { return op_; }
1934  Expression* target() const { return target_; }
1935  Expression* value() const { return value_; }
1936  virtual int position() const { return pos_; }
1937  BinaryOperation* binary_operation() const { return binary_operation_; }
1938
1939  // This check relies on the definition order of token in token.h.
1940  bool is_compound() const { return op() > Token::ASSIGN; }
1941
1942  // An initialization block is a series of statments of the form
1943  // x.y.z.a = ...; x.y.z.b = ...; etc. The parser marks the beginning and
1944  // ending of these blocks to allow for optimizations of initialization
1945  // blocks.
1946  bool starts_initialization_block() { return block_start_; }
1947  bool ends_initialization_block() { return block_end_; }
1948  void mark_block_start() { block_start_ = true; }
1949  void mark_block_end() { block_end_ = true; }
1950
1951  // Type feedback information.
1952  void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1953  virtual bool IsMonomorphic() { return is_monomorphic_; }
1954  virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
1955
1956  // Bailout support.
1957  int CompoundLoadId() const { return compound_load_id_; }
1958  int AssignmentId() const { return assignment_id_; }
1959
1960 protected:
1961  template<class> friend class AstNodeFactory;
1962
1963  Assignment(Isolate* isolate,
1964             Token::Value op,
1965             Expression* target,
1966             Expression* value,
1967             int pos);
1968
1969  template<class Visitor>
1970  void Init(Isolate* isolate, AstNodeFactory<Visitor>* factory) {
1971    ASSERT(Token::IsAssignmentOp(op_));
1972    if (is_compound()) {
1973      binary_operation_ =
1974          factory->NewBinaryOperation(binary_op(), target_, value_, pos_ + 1);
1975      compound_load_id_ = GetNextId(isolate);
1976    }
1977  }
1978
1979 private:
1980  Token::Value op_;
1981  Expression* target_;
1982  Expression* value_;
1983  int pos_;
1984  BinaryOperation* binary_operation_;
1985  int compound_load_id_;
1986  int assignment_id_;
1987
1988  bool block_start_;
1989  bool block_end_;
1990
1991  bool is_monomorphic_;
1992  SmallMapList receiver_types_;
1993};
1994
1995
1996class Throw: public Expression {
1997 public:
1998  DECLARE_NODE_TYPE(Throw)
1999
2000  Expression* exception() const { return exception_; }
2001  virtual int position() const { return pos_; }
2002
2003 protected:
2004  template<class> friend class AstNodeFactory;
2005
2006  Throw(Isolate* isolate, Expression* exception, int pos)
2007      : Expression(isolate), exception_(exception), pos_(pos) {}
2008
2009 private:
2010  Expression* exception_;
2011  int pos_;
2012};
2013
2014
2015class FunctionLiteral: public Expression {
2016 public:
2017  enum Type {
2018    ANONYMOUS_EXPRESSION,
2019    NAMED_EXPRESSION,
2020    DECLARATION
2021  };
2022
2023  enum ParameterFlag {
2024    kNoDuplicateParameters = 0,
2025    kHasDuplicateParameters = 1
2026  };
2027
2028  enum IsFunctionFlag {
2029    kGlobalOrEval,
2030    kIsFunction
2031  };
2032
2033  DECLARE_NODE_TYPE(FunctionLiteral)
2034
2035  Handle<String> name() const { return name_; }
2036  Scope* scope() const { return scope_; }
2037  ZoneList<Statement*>* body() const { return body_; }
2038  void set_function_token_position(int pos) { function_token_position_ = pos; }
2039  int function_token_position() const { return function_token_position_; }
2040  int start_position() const;
2041  int end_position() const;
2042  int SourceSize() const { return end_position() - start_position(); }
2043  bool is_expression() const { return IsExpression::decode(bitfield_); }
2044  bool is_anonymous() const { return IsAnonymous::decode(bitfield_); }
2045  bool is_classic_mode() const { return language_mode() == CLASSIC_MODE; }
2046  LanguageMode language_mode() const;
2047
2048  int materialized_literal_count() { return materialized_literal_count_; }
2049  int expected_property_count() { return expected_property_count_; }
2050  int handler_count() { return handler_count_; }
2051  bool has_only_simple_this_property_assignments() {
2052    return HasOnlySimpleThisPropertyAssignments::decode(bitfield_);
2053  }
2054  Handle<FixedArray> this_property_assignments() {
2055      return this_property_assignments_;
2056  }
2057  int parameter_count() { return parameter_count_; }
2058
2059  bool AllowsLazyCompilation();
2060
2061  Handle<String> debug_name() const {
2062    if (name_->length() > 0) return name_;
2063    return inferred_name();
2064  }
2065
2066  Handle<String> inferred_name() const { return inferred_name_; }
2067  void set_inferred_name(Handle<String> inferred_name) {
2068    inferred_name_ = inferred_name;
2069  }
2070
2071  bool pretenure() { return Pretenure::decode(bitfield_); }
2072  void set_pretenure() { bitfield_ |= Pretenure::encode(true); }
2073
2074  bool has_duplicate_parameters() {
2075    return HasDuplicateParameters::decode(bitfield_);
2076  }
2077
2078  bool is_function() { return IsFunction::decode(bitfield_) == kIsFunction; }
2079
2080  int ast_node_count() { return ast_properties_.node_count(); }
2081  AstProperties::Flags* flags() { return ast_properties_.flags(); }
2082  void set_ast_properties(AstProperties* ast_properties) {
2083    ast_properties_ = *ast_properties;
2084  }
2085
2086 protected:
2087  template<class> friend class AstNodeFactory;
2088
2089  FunctionLiteral(Isolate* isolate,
2090                  Handle<String> name,
2091                  Scope* scope,
2092                  ZoneList<Statement*>* body,
2093                  int materialized_literal_count,
2094                  int expected_property_count,
2095                  int handler_count,
2096                  bool has_only_simple_this_property_assignments,
2097                  Handle<FixedArray> this_property_assignments,
2098                  int parameter_count,
2099                  Type type,
2100                  ParameterFlag has_duplicate_parameters,
2101                  IsFunctionFlag is_function)
2102      : Expression(isolate),
2103        name_(name),
2104        scope_(scope),
2105        body_(body),
2106        this_property_assignments_(this_property_assignments),
2107        inferred_name_(isolate->factory()->empty_string()),
2108        materialized_literal_count_(materialized_literal_count),
2109        expected_property_count_(expected_property_count),
2110        handler_count_(handler_count),
2111        parameter_count_(parameter_count),
2112        function_token_position_(RelocInfo::kNoPosition) {
2113    bitfield_ =
2114        HasOnlySimpleThisPropertyAssignments::encode(
2115            has_only_simple_this_property_assignments) |
2116        IsExpression::encode(type != DECLARATION) |
2117        IsAnonymous::encode(type == ANONYMOUS_EXPRESSION) |
2118        Pretenure::encode(false) |
2119        HasDuplicateParameters::encode(has_duplicate_parameters) |
2120        IsFunction::encode(is_function);
2121  }
2122
2123 private:
2124  Handle<String> name_;
2125  Scope* scope_;
2126  ZoneList<Statement*>* body_;
2127  Handle<FixedArray> this_property_assignments_;
2128  Handle<String> inferred_name_;
2129  AstProperties ast_properties_;
2130
2131  int materialized_literal_count_;
2132  int expected_property_count_;
2133  int handler_count_;
2134  int parameter_count_;
2135  int function_token_position_;
2136
2137  unsigned bitfield_;
2138  class HasOnlySimpleThisPropertyAssignments: public BitField<bool, 0, 1> {};
2139  class IsExpression: public BitField<bool, 1, 1> {};
2140  class IsAnonymous: public BitField<bool, 2, 1> {};
2141  class Pretenure: public BitField<bool, 3, 1> {};
2142  class HasDuplicateParameters: public BitField<ParameterFlag, 4, 1> {};
2143  class IsFunction: public BitField<IsFunctionFlag, 5, 1> {};
2144};
2145
2146
2147class SharedFunctionInfoLiteral: public Expression {
2148 public:
2149  DECLARE_NODE_TYPE(SharedFunctionInfoLiteral)
2150
2151  Handle<SharedFunctionInfo> shared_function_info() const {
2152    return shared_function_info_;
2153  }
2154
2155 protected:
2156  template<class> friend class AstNodeFactory;
2157
2158  SharedFunctionInfoLiteral(
2159      Isolate* isolate,
2160      Handle<SharedFunctionInfo> shared_function_info)
2161      : Expression(isolate),
2162        shared_function_info_(shared_function_info) { }
2163
2164 private:
2165  Handle<SharedFunctionInfo> shared_function_info_;
2166};
2167
2168
2169class ThisFunction: public Expression {
2170 public:
2171  DECLARE_NODE_TYPE(ThisFunction)
2172
2173 protected:
2174  template<class> friend class AstNodeFactory;
2175
2176  explicit ThisFunction(Isolate* isolate): Expression(isolate) {}
2177};
2178
2179#undef DECLARE_NODE_TYPE
2180
2181
2182// ----------------------------------------------------------------------------
2183// Regular expressions
2184
2185
2186class RegExpVisitor BASE_EMBEDDED {
2187 public:
2188  virtual ~RegExpVisitor() { }
2189#define MAKE_CASE(Name)                                              \
2190  virtual void* Visit##Name(RegExp##Name*, void* data) = 0;
2191  FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
2192#undef MAKE_CASE
2193};
2194
2195
2196class RegExpTree: public ZoneObject {
2197 public:
2198  static const int kInfinity = kMaxInt;
2199  virtual ~RegExpTree() { }
2200  virtual void* Accept(RegExpVisitor* visitor, void* data) = 0;
2201  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2202                             RegExpNode* on_success) = 0;
2203  virtual bool IsTextElement() { return false; }
2204  virtual bool IsAnchoredAtStart() { return false; }
2205  virtual bool IsAnchoredAtEnd() { return false; }
2206  virtual int min_match() = 0;
2207  virtual int max_match() = 0;
2208  // Returns the interval of registers used for captures within this
2209  // expression.
2210  virtual Interval CaptureRegisters() { return Interval::Empty(); }
2211  virtual void AppendToText(RegExpText* text);
2212  SmartArrayPointer<const char> ToString();
2213#define MAKE_ASTYPE(Name)                                                  \
2214  virtual RegExp##Name* As##Name();                                        \
2215  virtual bool Is##Name();
2216  FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE)
2217#undef MAKE_ASTYPE
2218};
2219
2220
2221class RegExpDisjunction: public RegExpTree {
2222 public:
2223  explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives);
2224  virtual void* Accept(RegExpVisitor* visitor, void* data);
2225  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2226                             RegExpNode* on_success);
2227  virtual RegExpDisjunction* AsDisjunction();
2228  virtual Interval CaptureRegisters();
2229  virtual bool IsDisjunction();
2230  virtual bool IsAnchoredAtStart();
2231  virtual bool IsAnchoredAtEnd();
2232  virtual int min_match() { return min_match_; }
2233  virtual int max_match() { return max_match_; }
2234  ZoneList<RegExpTree*>* alternatives() { return alternatives_; }
2235 private:
2236  ZoneList<RegExpTree*>* alternatives_;
2237  int min_match_;
2238  int max_match_;
2239};
2240
2241
2242class RegExpAlternative: public RegExpTree {
2243 public:
2244  explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes);
2245  virtual void* Accept(RegExpVisitor* visitor, void* data);
2246  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2247                             RegExpNode* on_success);
2248  virtual RegExpAlternative* AsAlternative();
2249  virtual Interval CaptureRegisters();
2250  virtual bool IsAlternative();
2251  virtual bool IsAnchoredAtStart();
2252  virtual bool IsAnchoredAtEnd();
2253  virtual int min_match() { return min_match_; }
2254  virtual int max_match() { return max_match_; }
2255  ZoneList<RegExpTree*>* nodes() { return nodes_; }
2256 private:
2257  ZoneList<RegExpTree*>* nodes_;
2258  int min_match_;
2259  int max_match_;
2260};
2261
2262
2263class RegExpAssertion: public RegExpTree {
2264 public:
2265  enum Type {
2266    START_OF_LINE,
2267    START_OF_INPUT,
2268    END_OF_LINE,
2269    END_OF_INPUT,
2270    BOUNDARY,
2271    NON_BOUNDARY
2272  };
2273  explicit RegExpAssertion(Type type) : type_(type) { }
2274  virtual void* Accept(RegExpVisitor* visitor, void* data);
2275  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2276                             RegExpNode* on_success);
2277  virtual RegExpAssertion* AsAssertion();
2278  virtual bool IsAssertion();
2279  virtual bool IsAnchoredAtStart();
2280  virtual bool IsAnchoredAtEnd();
2281  virtual int min_match() { return 0; }
2282  virtual int max_match() { return 0; }
2283  Type type() { return type_; }
2284 private:
2285  Type type_;
2286};
2287
2288
2289class CharacterSet BASE_EMBEDDED {
2290 public:
2291  explicit CharacterSet(uc16 standard_set_type)
2292      : ranges_(NULL),
2293        standard_set_type_(standard_set_type) {}
2294  explicit CharacterSet(ZoneList<CharacterRange>* ranges)
2295      : ranges_(ranges),
2296        standard_set_type_(0) {}
2297  ZoneList<CharacterRange>* ranges();
2298  uc16 standard_set_type() { return standard_set_type_; }
2299  void set_standard_set_type(uc16 special_set_type) {
2300    standard_set_type_ = special_set_type;
2301  }
2302  bool is_standard() { return standard_set_type_ != 0; }
2303  void Canonicalize();
2304 private:
2305  ZoneList<CharacterRange>* ranges_;
2306  // If non-zero, the value represents a standard set (e.g., all whitespace
2307  // characters) without having to expand the ranges.
2308  uc16 standard_set_type_;
2309};
2310
2311
2312class RegExpCharacterClass: public RegExpTree {
2313 public:
2314  RegExpCharacterClass(ZoneList<CharacterRange>* ranges, bool is_negated)
2315      : set_(ranges),
2316        is_negated_(is_negated) { }
2317  explicit RegExpCharacterClass(uc16 type)
2318      : set_(type),
2319        is_negated_(false) { }
2320  virtual void* Accept(RegExpVisitor* visitor, void* data);
2321  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2322                             RegExpNode* on_success);
2323  virtual RegExpCharacterClass* AsCharacterClass();
2324  virtual bool IsCharacterClass();
2325  virtual bool IsTextElement() { return true; }
2326  virtual int min_match() { return 1; }
2327  virtual int max_match() { return 1; }
2328  virtual void AppendToText(RegExpText* text);
2329  CharacterSet character_set() { return set_; }
2330  // TODO(lrn): Remove need for complex version if is_standard that
2331  // recognizes a mangled standard set and just do { return set_.is_special(); }
2332  bool is_standard();
2333  // Returns a value representing the standard character set if is_standard()
2334  // returns true.
2335  // Currently used values are:
2336  // s : unicode whitespace
2337  // S : unicode non-whitespace
2338  // w : ASCII word character (digit, letter, underscore)
2339  // W : non-ASCII word character
2340  // d : ASCII digit
2341  // D : non-ASCII digit
2342  // . : non-unicode non-newline
2343  // * : All characters
2344  uc16 standard_type() { return set_.standard_set_type(); }
2345  ZoneList<CharacterRange>* ranges() { return set_.ranges(); }
2346  bool is_negated() { return is_negated_; }
2347
2348 private:
2349  CharacterSet set_;
2350  bool is_negated_;
2351};
2352
2353
2354class RegExpAtom: public RegExpTree {
2355 public:
2356  explicit RegExpAtom(Vector<const uc16> data) : data_(data) { }
2357  virtual void* Accept(RegExpVisitor* visitor, void* data);
2358  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2359                             RegExpNode* on_success);
2360  virtual RegExpAtom* AsAtom();
2361  virtual bool IsAtom();
2362  virtual bool IsTextElement() { return true; }
2363  virtual int min_match() { return data_.length(); }
2364  virtual int max_match() { return data_.length(); }
2365  virtual void AppendToText(RegExpText* text);
2366  Vector<const uc16> data() { return data_; }
2367  int length() { return data_.length(); }
2368 private:
2369  Vector<const uc16> data_;
2370};
2371
2372
2373class RegExpText: public RegExpTree {
2374 public:
2375  RegExpText() : elements_(2), length_(0) {}
2376  virtual void* Accept(RegExpVisitor* visitor, void* data);
2377  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2378                             RegExpNode* on_success);
2379  virtual RegExpText* AsText();
2380  virtual bool IsText();
2381  virtual bool IsTextElement() { return true; }
2382  virtual int min_match() { return length_; }
2383  virtual int max_match() { return length_; }
2384  virtual void AppendToText(RegExpText* text);
2385  void AddElement(TextElement elm)  {
2386    elements_.Add(elm);
2387    length_ += elm.length();
2388  }
2389  ZoneList<TextElement>* elements() { return &elements_; }
2390 private:
2391  ZoneList<TextElement> elements_;
2392  int length_;
2393};
2394
2395
2396class RegExpQuantifier: public RegExpTree {
2397 public:
2398  enum Type { GREEDY, NON_GREEDY, POSSESSIVE };
2399  RegExpQuantifier(int min, int max, Type type, RegExpTree* body)
2400      : body_(body),
2401        min_(min),
2402        max_(max),
2403        min_match_(min * body->min_match()),
2404        type_(type) {
2405    if (max > 0 && body->max_match() > kInfinity / max) {
2406      max_match_ = kInfinity;
2407    } else {
2408      max_match_ = max * body->max_match();
2409    }
2410  }
2411  virtual void* Accept(RegExpVisitor* visitor, void* data);
2412  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2413                             RegExpNode* on_success);
2414  static RegExpNode* ToNode(int min,
2415                            int max,
2416                            bool is_greedy,
2417                            RegExpTree* body,
2418                            RegExpCompiler* compiler,
2419                            RegExpNode* on_success,
2420                            bool not_at_start = false);
2421  virtual RegExpQuantifier* AsQuantifier();
2422  virtual Interval CaptureRegisters();
2423  virtual bool IsQuantifier();
2424  virtual int min_match() { return min_match_; }
2425  virtual int max_match() { return max_match_; }
2426  int min() { return min_; }
2427  int max() { return max_; }
2428  bool is_possessive() { return type_ == POSSESSIVE; }
2429  bool is_non_greedy() { return type_ == NON_GREEDY; }
2430  bool is_greedy() { return type_ == GREEDY; }
2431  RegExpTree* body() { return body_; }
2432
2433 private:
2434  RegExpTree* body_;
2435  int min_;
2436  int max_;
2437  int min_match_;
2438  int max_match_;
2439  Type type_;
2440};
2441
2442
2443class RegExpCapture: public RegExpTree {
2444 public:
2445  explicit RegExpCapture(RegExpTree* body, int index)
2446      : body_(body), index_(index) { }
2447  virtual void* Accept(RegExpVisitor* visitor, void* data);
2448  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2449                             RegExpNode* on_success);
2450  static RegExpNode* ToNode(RegExpTree* body,
2451                            int index,
2452                            RegExpCompiler* compiler,
2453                            RegExpNode* on_success);
2454  virtual RegExpCapture* AsCapture();
2455  virtual bool IsAnchoredAtStart();
2456  virtual bool IsAnchoredAtEnd();
2457  virtual Interval CaptureRegisters();
2458  virtual bool IsCapture();
2459  virtual int min_match() { return body_->min_match(); }
2460  virtual int max_match() { return body_->max_match(); }
2461  RegExpTree* body() { return body_; }
2462  int index() { return index_; }
2463  static int StartRegister(int index) { return index * 2; }
2464  static int EndRegister(int index) { return index * 2 + 1; }
2465
2466 private:
2467  RegExpTree* body_;
2468  int index_;
2469};
2470
2471
2472class RegExpLookahead: public RegExpTree {
2473 public:
2474  RegExpLookahead(RegExpTree* body,
2475                  bool is_positive,
2476                  int capture_count,
2477                  int capture_from)
2478      : body_(body),
2479        is_positive_(is_positive),
2480        capture_count_(capture_count),
2481        capture_from_(capture_from) { }
2482
2483  virtual void* Accept(RegExpVisitor* visitor, void* data);
2484  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2485                             RegExpNode* on_success);
2486  virtual RegExpLookahead* AsLookahead();
2487  virtual Interval CaptureRegisters();
2488  virtual bool IsLookahead();
2489  virtual bool IsAnchoredAtStart();
2490  virtual int min_match() { return 0; }
2491  virtual int max_match() { return 0; }
2492  RegExpTree* body() { return body_; }
2493  bool is_positive() { return is_positive_; }
2494  int capture_count() { return capture_count_; }
2495  int capture_from() { return capture_from_; }
2496
2497 private:
2498  RegExpTree* body_;
2499  bool is_positive_;
2500  int capture_count_;
2501  int capture_from_;
2502};
2503
2504
2505class RegExpBackReference: public RegExpTree {
2506 public:
2507  explicit RegExpBackReference(RegExpCapture* capture)
2508      : capture_(capture) { }
2509  virtual void* Accept(RegExpVisitor* visitor, void* data);
2510  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2511                             RegExpNode* on_success);
2512  virtual RegExpBackReference* AsBackReference();
2513  virtual bool IsBackReference();
2514  virtual int min_match() { return 0; }
2515  virtual int max_match() { return capture_->max_match(); }
2516  int index() { return capture_->index(); }
2517  RegExpCapture* capture() { return capture_; }
2518 private:
2519  RegExpCapture* capture_;
2520};
2521
2522
2523class RegExpEmpty: public RegExpTree {
2524 public:
2525  RegExpEmpty() { }
2526  virtual void* Accept(RegExpVisitor* visitor, void* data);
2527  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2528                             RegExpNode* on_success);
2529  virtual RegExpEmpty* AsEmpty();
2530  virtual bool IsEmpty();
2531  virtual int min_match() { return 0; }
2532  virtual int max_match() { return 0; }
2533  static RegExpEmpty* GetInstance() {
2534    static RegExpEmpty* instance = ::new RegExpEmpty();
2535    return instance;
2536  }
2537};
2538
2539
2540// ----------------------------------------------------------------------------
2541// Out-of-line inline constructors (to side-step cyclic dependencies).
2542
2543inline ModuleVariable::ModuleVariable(VariableProxy* proxy)
2544    : Module(proxy->interface()),
2545      proxy_(proxy) {
2546}
2547
2548
2549// ----------------------------------------------------------------------------
2550// Basic visitor
2551// - leaf node visitors are abstract.
2552
2553class AstVisitor BASE_EMBEDDED {
2554 public:
2555  AstVisitor() : isolate_(Isolate::Current()), stack_overflow_(false) { }
2556  virtual ~AstVisitor() { }
2557
2558  // Stack overflow check and dynamic dispatch.
2559  void Visit(AstNode* node) { if (!CheckStackOverflow()) node->Accept(this); }
2560
2561  // Iteration left-to-right.
2562  virtual void VisitDeclarations(ZoneList<Declaration*>* declarations);
2563  virtual void VisitStatements(ZoneList<Statement*>* statements);
2564  virtual void VisitExpressions(ZoneList<Expression*>* expressions);
2565
2566  // Stack overflow tracking support.
2567  bool HasStackOverflow() const { return stack_overflow_; }
2568  bool CheckStackOverflow();
2569
2570  // If a stack-overflow exception is encountered when visiting a
2571  // node, calling SetStackOverflow will make sure that the visitor
2572  // bails out without visiting more nodes.
2573  void SetStackOverflow() { stack_overflow_ = true; }
2574  void ClearStackOverflow() { stack_overflow_ = false; }
2575
2576  // Individual AST nodes.
2577#define DEF_VISIT(type)                         \
2578  virtual void Visit##type(type* node) = 0;
2579  AST_NODE_LIST(DEF_VISIT)
2580#undef DEF_VISIT
2581
2582 protected:
2583  Isolate* isolate() { return isolate_; }
2584
2585 private:
2586  Isolate* isolate_;
2587  bool stack_overflow_;
2588};
2589
2590
2591// ----------------------------------------------------------------------------
2592// Construction time visitor.
2593
2594class AstConstructionVisitor BASE_EMBEDDED {
2595 public:
2596  AstConstructionVisitor() { }
2597
2598  AstProperties* ast_properties() { return &properties_; }
2599
2600 private:
2601  template<class> friend class AstNodeFactory;
2602
2603  // Node visitors.
2604#define DEF_VISIT(type) \
2605  void Visit##type(type* node);
2606  AST_NODE_LIST(DEF_VISIT)
2607#undef DEF_VISIT
2608
2609  void increase_node_count() { properties_.add_node_count(1); }
2610  void add_flag(AstPropertiesFlag flag) { properties_.flags()->Add(flag); }
2611
2612  AstProperties properties_;
2613};
2614
2615
2616class AstNullVisitor BASE_EMBEDDED {
2617 public:
2618  // Node visitors.
2619#define DEF_VISIT(type) \
2620  void Visit##type(type* node) {}
2621  AST_NODE_LIST(DEF_VISIT)
2622#undef DEF_VISIT
2623};
2624
2625
2626
2627// ----------------------------------------------------------------------------
2628// AstNode factory
2629
2630template<class Visitor>
2631class AstNodeFactory BASE_EMBEDDED {
2632 public:
2633  explicit AstNodeFactory(Isolate* isolate)
2634      : isolate_(isolate),
2635        zone_(isolate_->zone()) { }
2636
2637  Visitor* visitor() { return &visitor_; }
2638
2639#define VISIT_AND_RETURN(NodeType, node) \
2640  visitor_.Visit##NodeType((node)); \
2641  return node;
2642
2643  VariableDeclaration* NewVariableDeclaration(VariableProxy* proxy,
2644                                              VariableMode mode,
2645                                              Scope* scope) {
2646    VariableDeclaration* decl =
2647        new(zone_) VariableDeclaration(proxy, mode, scope);
2648    VISIT_AND_RETURN(VariableDeclaration, decl)
2649  }
2650
2651  FunctionDeclaration* NewFunctionDeclaration(VariableProxy* proxy,
2652                                              VariableMode mode,
2653                                              FunctionLiteral* fun,
2654                                              Scope* scope) {
2655    FunctionDeclaration* decl =
2656        new(zone_) FunctionDeclaration(proxy, mode, fun, scope);
2657    VISIT_AND_RETURN(FunctionDeclaration, decl)
2658  }
2659
2660  ModuleDeclaration* NewModuleDeclaration(VariableProxy* proxy,
2661                                          Module* module,
2662                                          Scope* scope) {
2663    ModuleDeclaration* decl =
2664        new(zone_) ModuleDeclaration(proxy, module, scope);
2665    VISIT_AND_RETURN(ModuleDeclaration, decl)
2666  }
2667
2668  ImportDeclaration* NewImportDeclaration(VariableProxy* proxy,
2669                                          Module* module,
2670                                          Scope* scope) {
2671    ImportDeclaration* decl =
2672        new(zone_) ImportDeclaration(proxy, module, scope);
2673    VISIT_AND_RETURN(ImportDeclaration, decl)
2674  }
2675
2676  ExportDeclaration* NewExportDeclaration(VariableProxy* proxy,
2677                                          Scope* scope) {
2678    ExportDeclaration* decl =
2679        new(zone_) ExportDeclaration(proxy, scope);
2680    VISIT_AND_RETURN(ExportDeclaration, decl)
2681  }
2682
2683  ModuleLiteral* NewModuleLiteral(Block* body, Interface* interface) {
2684    ModuleLiteral* module = new(zone_) ModuleLiteral(body, interface);
2685    VISIT_AND_RETURN(ModuleLiteral, module)
2686  }
2687
2688  ModuleVariable* NewModuleVariable(VariableProxy* proxy) {
2689    ModuleVariable* module = new(zone_) ModuleVariable(proxy);
2690    VISIT_AND_RETURN(ModuleVariable, module)
2691  }
2692
2693  ModulePath* NewModulePath(Module* origin, Handle<String> name) {
2694    ModulePath* module = new(zone_) ModulePath(origin, name);
2695    VISIT_AND_RETURN(ModulePath, module)
2696  }
2697
2698  ModuleUrl* NewModuleUrl(Handle<String> url) {
2699    ModuleUrl* module = new(zone_) ModuleUrl(url);
2700    VISIT_AND_RETURN(ModuleUrl, module)
2701  }
2702
2703  Block* NewBlock(ZoneStringList* labels,
2704                  int capacity,
2705                  bool is_initializer_block) {
2706    Block* block = new(zone_) Block(
2707        isolate_, labels, capacity, is_initializer_block);
2708    VISIT_AND_RETURN(Block, block)
2709  }
2710
2711#define STATEMENT_WITH_LABELS(NodeType) \
2712  NodeType* New##NodeType(ZoneStringList* labels) { \
2713    NodeType* stmt = new(zone_) NodeType(isolate_, labels); \
2714    VISIT_AND_RETURN(NodeType, stmt); \
2715  }
2716  STATEMENT_WITH_LABELS(DoWhileStatement)
2717  STATEMENT_WITH_LABELS(WhileStatement)
2718  STATEMENT_WITH_LABELS(ForStatement)
2719  STATEMENT_WITH_LABELS(ForInStatement)
2720  STATEMENT_WITH_LABELS(SwitchStatement)
2721#undef STATEMENT_WITH_LABELS
2722
2723  ExpressionStatement* NewExpressionStatement(Expression* expression) {
2724    ExpressionStatement* stmt = new(zone_) ExpressionStatement(expression);
2725    VISIT_AND_RETURN(ExpressionStatement, stmt)
2726  }
2727
2728  ContinueStatement* NewContinueStatement(IterationStatement* target) {
2729    ContinueStatement* stmt = new(zone_) ContinueStatement(target);
2730    VISIT_AND_RETURN(ContinueStatement, stmt)
2731  }
2732
2733  BreakStatement* NewBreakStatement(BreakableStatement* target) {
2734    BreakStatement* stmt = new(zone_) BreakStatement(target);
2735    VISIT_AND_RETURN(BreakStatement, stmt)
2736  }
2737
2738  ReturnStatement* NewReturnStatement(Expression* expression) {
2739    ReturnStatement* stmt = new(zone_) ReturnStatement(expression);
2740    VISIT_AND_RETURN(ReturnStatement, stmt)
2741  }
2742
2743  WithStatement* NewWithStatement(Expression* expression,
2744                                  Statement* statement) {
2745    WithStatement* stmt = new(zone_) WithStatement(expression, statement);
2746    VISIT_AND_RETURN(WithStatement, stmt)
2747  }
2748
2749  IfStatement* NewIfStatement(Expression* condition,
2750                              Statement* then_statement,
2751                              Statement* else_statement) {
2752    IfStatement* stmt = new(zone_) IfStatement(
2753        isolate_, condition, then_statement, else_statement);
2754    VISIT_AND_RETURN(IfStatement, stmt)
2755  }
2756
2757  TryCatchStatement* NewTryCatchStatement(int index,
2758                                          Block* try_block,
2759                                          Scope* scope,
2760                                          Variable* variable,
2761                                          Block* catch_block) {
2762    TryCatchStatement* stmt = new(zone_) TryCatchStatement(
2763        index, try_block, scope, variable, catch_block);
2764    VISIT_AND_RETURN(TryCatchStatement, stmt)
2765  }
2766
2767  TryFinallyStatement* NewTryFinallyStatement(int index,
2768                                              Block* try_block,
2769                                              Block* finally_block) {
2770    TryFinallyStatement* stmt =
2771        new(zone_) TryFinallyStatement(index, try_block, finally_block);
2772    VISIT_AND_RETURN(TryFinallyStatement, stmt)
2773  }
2774
2775  DebuggerStatement* NewDebuggerStatement() {
2776    DebuggerStatement* stmt = new(zone_) DebuggerStatement();
2777    VISIT_AND_RETURN(DebuggerStatement, stmt)
2778  }
2779
2780  EmptyStatement* NewEmptyStatement() {
2781    return new(zone_) EmptyStatement();
2782  }
2783
2784  Literal* NewLiteral(Handle<Object> handle) {
2785    Literal* lit = new(zone_) Literal(isolate_, handle);
2786    VISIT_AND_RETURN(Literal, lit)
2787  }
2788
2789  Literal* NewNumberLiteral(double number) {
2790    return NewLiteral(isolate_->factory()->NewNumber(number, TENURED));
2791  }
2792
2793  ObjectLiteral* NewObjectLiteral(
2794      Handle<FixedArray> constant_properties,
2795      ZoneList<ObjectLiteral::Property*>* properties,
2796      int literal_index,
2797      bool is_simple,
2798      bool fast_elements,
2799      int depth,
2800      bool has_function) {
2801    ObjectLiteral* lit = new(zone_) ObjectLiteral(
2802        isolate_, constant_properties, properties, literal_index,
2803        is_simple, fast_elements, depth, has_function);
2804    VISIT_AND_RETURN(ObjectLiteral, lit)
2805  }
2806
2807  ObjectLiteral::Property* NewObjectLiteralProperty(bool is_getter,
2808                                                    FunctionLiteral* value) {
2809    ObjectLiteral::Property* prop =
2810        new(zone_) ObjectLiteral::Property(is_getter, value);
2811    prop->set_key(NewLiteral(value->name()));
2812    return prop;  // Not an AST node, will not be visited.
2813  }
2814
2815  RegExpLiteral* NewRegExpLiteral(Handle<String> pattern,
2816                                  Handle<String> flags,
2817                                  int literal_index) {
2818    RegExpLiteral* lit =
2819        new(zone_) RegExpLiteral(isolate_, pattern, flags, literal_index);
2820    VISIT_AND_RETURN(RegExpLiteral, lit);
2821  }
2822
2823  ArrayLiteral* NewArrayLiteral(Handle<FixedArray> constant_elements,
2824                                ZoneList<Expression*>* values,
2825                                int literal_index,
2826                                bool is_simple,
2827                                int depth) {
2828    ArrayLiteral* lit = new(zone_) ArrayLiteral(
2829        isolate_, constant_elements, values, literal_index, is_simple, depth);
2830    VISIT_AND_RETURN(ArrayLiteral, lit)
2831  }
2832
2833  VariableProxy* NewVariableProxy(Variable* var) {
2834    VariableProxy* proxy = new(zone_) VariableProxy(isolate_, var);
2835    VISIT_AND_RETURN(VariableProxy, proxy)
2836  }
2837
2838  VariableProxy* NewVariableProxy(Handle<String> name,
2839                                  bool is_this,
2840                                  int position = RelocInfo::kNoPosition,
2841                                  Interface* interface =
2842                                      Interface::NewValue()) {
2843    VariableProxy* proxy =
2844        new(zone_) VariableProxy(isolate_, name, is_this, position, interface);
2845    VISIT_AND_RETURN(VariableProxy, proxy)
2846  }
2847
2848  Property* NewProperty(Expression* obj, Expression* key, int pos) {
2849    Property* prop = new(zone_) Property(isolate_, obj, key, pos);
2850    VISIT_AND_RETURN(Property, prop)
2851  }
2852
2853  Call* NewCall(Expression* expression,
2854                ZoneList<Expression*>* arguments,
2855                int pos) {
2856    Call* call = new(zone_) Call(isolate_, expression, arguments, pos);
2857    VISIT_AND_RETURN(Call, call)
2858  }
2859
2860  CallNew* NewCallNew(Expression* expression,
2861                      ZoneList<Expression*>* arguments,
2862                      int pos) {
2863    CallNew* call = new(zone_) CallNew(isolate_, expression, arguments, pos);
2864    VISIT_AND_RETURN(CallNew, call)
2865  }
2866
2867  CallRuntime* NewCallRuntime(Handle<String> name,
2868                              const Runtime::Function* function,
2869                              ZoneList<Expression*>* arguments) {
2870    CallRuntime* call =
2871        new(zone_) CallRuntime(isolate_, name, function, arguments);
2872    VISIT_AND_RETURN(CallRuntime, call)
2873  }
2874
2875  UnaryOperation* NewUnaryOperation(Token::Value op,
2876                                    Expression* expression,
2877                                    int pos) {
2878    UnaryOperation* node =
2879        new(zone_) UnaryOperation(isolate_, op, expression, pos);
2880    VISIT_AND_RETURN(UnaryOperation, node)
2881  }
2882
2883  BinaryOperation* NewBinaryOperation(Token::Value op,
2884                                      Expression* left,
2885                                      Expression* right,
2886                                      int pos) {
2887    BinaryOperation* node =
2888        new(zone_) BinaryOperation(isolate_, op, left, right, pos);
2889    VISIT_AND_RETURN(BinaryOperation, node)
2890  }
2891
2892  CountOperation* NewCountOperation(Token::Value op,
2893                                    bool is_prefix,
2894                                    Expression* expr,
2895                                    int pos) {
2896    CountOperation* node =
2897        new(zone_) CountOperation(isolate_, op, is_prefix, expr, pos);
2898    VISIT_AND_RETURN(CountOperation, node)
2899  }
2900
2901  CompareOperation* NewCompareOperation(Token::Value op,
2902                                        Expression* left,
2903                                        Expression* right,
2904                                        int pos) {
2905    CompareOperation* node =
2906        new(zone_) CompareOperation(isolate_, op, left, right, pos);
2907    VISIT_AND_RETURN(CompareOperation, node)
2908  }
2909
2910  Conditional* NewConditional(Expression* condition,
2911                              Expression* then_expression,
2912                              Expression* else_expression,
2913                              int then_expression_position,
2914                              int else_expression_position) {
2915    Conditional* cond = new(zone_) Conditional(
2916        isolate_, condition, then_expression, else_expression,
2917        then_expression_position, else_expression_position);
2918    VISIT_AND_RETURN(Conditional, cond)
2919  }
2920
2921  Assignment* NewAssignment(Token::Value op,
2922                            Expression* target,
2923                            Expression* value,
2924                            int pos) {
2925    Assignment* assign =
2926        new(zone_) Assignment(isolate_, op, target, value, pos);
2927    assign->Init(isolate_, this);
2928    VISIT_AND_RETURN(Assignment, assign)
2929  }
2930
2931  Throw* NewThrow(Expression* exception, int pos) {
2932    Throw* t = new(zone_) Throw(isolate_, exception, pos);
2933    VISIT_AND_RETURN(Throw, t)
2934  }
2935
2936  FunctionLiteral* NewFunctionLiteral(
2937      Handle<String> name,
2938      Scope* scope,
2939      ZoneList<Statement*>* body,
2940      int materialized_literal_count,
2941      int expected_property_count,
2942      int handler_count,
2943      bool has_only_simple_this_property_assignments,
2944      Handle<FixedArray> this_property_assignments,
2945      int parameter_count,
2946      FunctionLiteral::ParameterFlag has_duplicate_parameters,
2947      FunctionLiteral::Type type,
2948      FunctionLiteral::IsFunctionFlag is_function) {
2949    FunctionLiteral* lit = new(zone_) FunctionLiteral(
2950        isolate_, name, scope, body,
2951        materialized_literal_count, expected_property_count, handler_count,
2952        has_only_simple_this_property_assignments, this_property_assignments,
2953        parameter_count, type, has_duplicate_parameters, is_function);
2954    // Top-level literal doesn't count for the AST's properties.
2955    if (is_function == FunctionLiteral::kIsFunction) {
2956      visitor_.VisitFunctionLiteral(lit);
2957    }
2958    return lit;
2959  }
2960
2961  SharedFunctionInfoLiteral* NewSharedFunctionInfoLiteral(
2962      Handle<SharedFunctionInfo> shared_function_info) {
2963    SharedFunctionInfoLiteral* lit =
2964        new(zone_) SharedFunctionInfoLiteral(isolate_, shared_function_info);
2965    VISIT_AND_RETURN(SharedFunctionInfoLiteral, lit)
2966  }
2967
2968  ThisFunction* NewThisFunction() {
2969    ThisFunction* fun = new(zone_) ThisFunction(isolate_);
2970    VISIT_AND_RETURN(ThisFunction, fun)
2971  }
2972
2973#undef VISIT_AND_RETURN
2974
2975 private:
2976  Isolate* isolate_;
2977  Zone* zone_;
2978  Visitor visitor_;
2979};
2980
2981
2982} }  // namespace v8::internal
2983
2984#endif  // V8_AST_H_
2985