• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
47 namespace v8 {
48 namespace 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
122 class AstConstructionVisitor;
123 template<class> class AstNodeFactory;
124 class AstVisitor;
125 class Declaration;
126 class Module;
127 class BreakableStatement;
128 class Expression;
129 class IterationStatement;
130 class MaterializedLiteral;
131 class Statement;
132 class TargetCollector;
133 class TypeFeedbackOracle;
134 
135 class RegExpAlternative;
136 class RegExpAssertion;
137 class RegExpAtom;
138 class RegExpBackReference;
139 class RegExpCapture;
140 class RegExpCharacterClass;
141 class RegExpCompiler;
142 class RegExpDisjunction;
143 class RegExpEmpty;
144 class RegExpLookahead;
145 class RegExpQuantifier;
146 class RegExpText;
147 
148 #define DEF_FORWARD_DECLARATION(type) class type;
149 AST_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 "> >".
155 typedef ZoneList<Handle<String> > ZoneStringList;
156 typedef 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 
164 enum AstPropertiesFlag {
165   kDontInline,
166   kDontOptimize,
167   kDontSelfOptimize,
168   kDontSoftInline
169 };
170 
171 
172 class AstProperties BASE_EMBEDDED {
173  public:
174   class Flags : public EnumSet<AstPropertiesFlag, int> {};
175 
AstProperties()176   AstProperties() : node_count_(0) { }
177 
flags()178   Flags* flags() { return &flags_; }
node_count()179   int node_count() { return node_count_; }
add_node_count(int count)180   void add_node_count(int count) { node_count_ += count; }
181 
182  private:
183   Flags flags_;
184   int node_count_;
185 };
186 
187 
188 class 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 
new(size_t size,Zone * zone)204   void* operator new(size_t size, Zone* zone) {
205     return zone->New(static_cast<int>(size));
206   }
207 
AstNode()208   AstNode() { }
209 
~AstNode()210   virtual ~AstNode() { }
211 
212   virtual void Accept(AstVisitor* v) = 0;
node_type()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; }
AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)219   AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
220 #undef DECLARE_NODE_FUNCTIONS
221 
222   virtual Declaration* AsDeclaration() { return NULL; }
AsStatement()223   virtual Statement* AsStatement() { return NULL; }
AsExpression()224   virtual Expression* AsExpression() { return NULL; }
AsTargetCollector()225   virtual TargetCollector* AsTargetCollector() { return NULL; }
AsBreakableStatement()226   virtual BreakableStatement* AsBreakableStatement() { return NULL; }
AsIterationStatement()227   virtual IterationStatement* AsIterationStatement() { return NULL; }
AsMaterializedLiteral()228   virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; }
229 
230  protected:
GetNextId(Isolate * isolate)231   static int GetNextId(Isolate* isolate) {
232     return ReserveIdRange(isolate, 1);
233   }
234 
ReserveIdRange(Isolate * isolate,int n)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 
250 class Statement: public AstNode {
251  public:
Statement()252   Statement() : statement_pos_(RelocInfo::kNoPosition) {}
253 
AsStatement()254   virtual Statement* AsStatement()  { return this; }
255 
IsEmpty()256   bool IsEmpty() { return AsEmptyStatement() != NULL; }
257 
set_statement_pos(int statement_pos)258   void set_statement_pos(int statement_pos) { statement_pos_ = statement_pos; }
statement_pos()259   int statement_pos() const { return statement_pos_; }
260 
261  private:
262   int statement_pos_;
263 };
264 
265 
266 class SmallMapList {
267  public:
SmallMapList()268   SmallMapList() {}
SmallMapList(int capacity)269   explicit SmallMapList(int capacity) : list_(capacity) {}
270 
Reserve(int capacity)271   void Reserve(int capacity) { list_.Reserve(capacity); }
Clear()272   void Clear() { list_.Clear(); }
273 
is_empty()274   bool is_empty() const { return list_.is_empty(); }
length()275   int length() const { return list_.length(); }
276 
Add(Handle<Map> handle)277   void Add(Handle<Map> handle) {
278     list_.Add(handle.location());
279   }
280 
at(int i)281   Handle<Map> at(int i) const {
282     return Handle<Map>(list_.at(i));
283   }
284 
first()285   Handle<Map> first() const { return at(0); }
last()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 
296 class 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 
position()310   virtual int position() const {
311     UNREACHABLE();
312     return 0;
313   }
314 
AsExpression()315   virtual Expression* AsExpression()  { return this; }
316 
IsValidLeftHandSide()317   virtual bool IsValidLeftHandSide() { return false; }
318 
319   // Helpers for ToBoolean conversion.
ToBooleanIsTrue()320   virtual bool ToBooleanIsTrue() { return false; }
ToBooleanIsFalse()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.
IsPropertyName()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.
ResultOverwriteAllowed()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.
IsMonomorphic()342   virtual bool IsMonomorphic() {
343     UNREACHABLE();
344     return false;
345   }
GetReceiverTypes()346   virtual SmallMapList* GetReceiverTypes() {
347     UNREACHABLE();
348     return NULL;
349   }
GetMonomorphicReceiverType()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 
id()357   unsigned id() const { return id_; }
test_id()358   unsigned test_id() const { return test_id_; }
359 
360  protected:
Expression(Isolate * isolate)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 
371 class 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.
labels()380   ZoneStringList* labels() const { return labels_; }
381 
382   // Type testing & conversion.
AsBreakableStatement()383   virtual BreakableStatement* AsBreakableStatement() { return this; }
384 
385   // Code generation
break_target()386   Label* break_target() { return &break_target_; }
387 
388   // Testers.
is_target_for_anonymous()389   bool is_target_for_anonymous() const { return type_ == TARGET_FOR_ANONYMOUS; }
390 
391   // Bailout support.
EntryId()392   int EntryId() const { return entry_id_; }
ExitId()393   int ExitId() const { return exit_id_; }
394 
395  protected:
BreakableStatement(Isolate * isolate,ZoneStringList * labels,Type type)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 
414 class Block: public BreakableStatement {
415  public:
DECLARE_NODE_TYPE(Block)416   DECLARE_NODE_TYPE(Block)
417 
418   void AddStatement(Statement* statement) { statements_.Add(statement); }
419 
statements()420   ZoneList<Statement*>* statements() { return &statements_; }
is_initializer_block()421   bool is_initializer_block() const { return is_initializer_block_; }
422 
block_scope()423   Scope* block_scope() const { return block_scope_; }
set_block_scope(Scope * block_scope)424   void set_block_scope(Scope* block_scope) { block_scope_ = block_scope; }
425 
426  protected:
427   template<class> friend class AstNodeFactory;
428 
Block(Isolate * isolate,ZoneStringList * labels,int capacity,bool is_initializer_block)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 
446 class Declaration: public AstNode {
447  public:
proxy()448   VariableProxy* proxy() const { return proxy_; }
mode()449   VariableMode mode() const { return mode_; }
scope()450   Scope* scope() const { return scope_; }
451   virtual InitializationFlag initialization() const = 0;
452   virtual bool IsInlineable() const;
453 
AsDeclaration()454   virtual Declaration* AsDeclaration() { return this; }
455 
456  protected:
Declaration(VariableProxy * proxy,VariableMode mode,Scope * scope)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 
478 class VariableDeclaration: public Declaration {
479  public:
DECLARE_NODE_TYPE(VariableDeclaration)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 
VariableDeclaration(VariableProxy * proxy,VariableMode mode,Scope * scope)489   VariableDeclaration(VariableProxy* proxy,
490                       VariableMode mode,
491                       Scope* scope)
492       : Declaration(proxy, mode, scope) {
493   }
494 };
495 
496 
497 class FunctionDeclaration: public Declaration {
498  public:
DECLARE_NODE_TYPE(FunctionDeclaration)499   DECLARE_NODE_TYPE(FunctionDeclaration)
500 
501   FunctionLiteral* fun() const { return fun_; }
initialization()502   virtual InitializationFlag initialization() const {
503     return kCreatedInitialized;
504   }
505   virtual bool IsInlineable() const;
506 
507  protected:
508   template<class> friend class AstNodeFactory;
509 
FunctionDeclaration(VariableProxy * proxy,VariableMode mode,FunctionLiteral * fun,Scope * scope)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 
526 class ModuleDeclaration: public Declaration {
527  public:
DECLARE_NODE_TYPE(ModuleDeclaration)528   DECLARE_NODE_TYPE(ModuleDeclaration)
529 
530   Module* module() const { return module_; }
initialization()531   virtual InitializationFlag initialization() const {
532     return kCreatedInitialized;
533   }
534 
535  protected:
536   template<class> friend class AstNodeFactory;
537 
ModuleDeclaration(VariableProxy * proxy,Module * module,Scope * scope)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 
550 class ImportDeclaration: public Declaration {
551  public:
DECLARE_NODE_TYPE(ImportDeclaration)552   DECLARE_NODE_TYPE(ImportDeclaration)
553 
554   Module* module() const { return module_; }
initialization()555   virtual InitializationFlag initialization() const {
556     return kCreatedInitialized;
557   }
558 
559  protected:
560   template<class> friend class AstNodeFactory;
561 
ImportDeclaration(VariableProxy * proxy,Module * module,Scope * scope)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 
574 class ExportDeclaration: public Declaration {
575  public:
DECLARE_NODE_TYPE(ExportDeclaration)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 
ExportDeclaration(VariableProxy * proxy,Scope * scope)585   ExportDeclaration(VariableProxy* proxy,
586                     Scope* scope)
587       : Declaration(proxy, LET, scope) {
588   }
589 };
590 
591 
592 class Module: public AstNode {
593  public:
interface()594   Interface* interface() const { return interface_; }
595 
596  protected:
Module()597   Module() : interface_(Interface::NewModule()) {}
Module(Interface * interface)598   explicit Module(Interface* interface) : interface_(interface) {}
599 
600  private:
601   Interface* interface_;
602 };
603 
604 
605 class ModuleLiteral: public Module {
606  public:
DECLARE_NODE_TYPE(ModuleLiteral)607   DECLARE_NODE_TYPE(ModuleLiteral)
608 
609   Block* body() const { return body_; }
610 
611  protected:
612   template<class> friend class AstNodeFactory;
613 
ModuleLiteral(Block * body,Interface * interface)614   ModuleLiteral(Block* body, Interface* interface)
615       : Module(interface),
616         body_(body) {
617   }
618 
619  private:
620   Block* body_;
621 };
622 
623 
624 class ModuleVariable: public Module {
625  public:
DECLARE_NODE_TYPE(ModuleVariable)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 
640 class ModulePath: public Module {
641  public:
DECLARE_NODE_TYPE(ModulePath)642   DECLARE_NODE_TYPE(ModulePath)
643 
644   Module* module() const { return module_; }
name()645   Handle<String> name() const { return name_; }
646 
647  protected:
648   template<class> friend class AstNodeFactory;
649 
ModulePath(Module * module,Handle<String> name)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 
661 class ModuleUrl: public Module {
662  public:
DECLARE_NODE_TYPE(ModuleUrl)663   DECLARE_NODE_TYPE(ModuleUrl)
664 
665   Handle<String> url() const { return url_; }
666 
667  protected:
668   template<class> friend class AstNodeFactory;
669 
ModuleUrl(Handle<String> url)670   explicit ModuleUrl(Handle<String> url) : url_(url) {
671   }
672 
673  private:
674   Handle<String> url_;
675 };
676 
677 
678 class IterationStatement: public BreakableStatement {
679  public:
680   // Type testing & conversion.
AsIterationStatement()681   virtual IterationStatement* AsIterationStatement() { return this; }
682 
body()683   Statement* body() const { return body_; }
684 
685   // Bailout support.
OsrEntryId()686   int OsrEntryId() const { return osr_entry_id_; }
687   virtual int ContinueId() const = 0;
688   virtual int StackCheckId() const = 0;
689 
690   // Code generation
continue_target()691   Label* continue_target()  { return &continue_target_; }
692 
693  protected:
IterationStatement(Isolate * isolate,ZoneStringList * labels)694   IterationStatement(Isolate* isolate, ZoneStringList* labels)
695       : BreakableStatement(isolate, labels, TARGET_FOR_ANONYMOUS),
696         body_(NULL),
697         osr_entry_id_(GetNextId(isolate)) {
698   }
699 
Initialize(Statement * body)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 
711 class DoWhileStatement: public IterationStatement {
712  public:
DECLARE_NODE_TYPE(DoWhileStatement)713   DECLARE_NODE_TYPE(DoWhileStatement)
714 
715   void Initialize(Expression* cond, Statement* body) {
716     IterationStatement::Initialize(body);
717     cond_ = cond;
718   }
719 
cond()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.
condition_position()724   int condition_position() { return condition_position_; }
set_condition_position(int pos)725   void set_condition_position(int pos) { condition_position_ = pos; }
726 
727   // Bailout support.
ContinueId()728   virtual int ContinueId() const { return continue_id_; }
StackCheckId()729   virtual int StackCheckId() const { return back_edge_id_; }
BackEdgeId()730   int BackEdgeId() const { return back_edge_id_; }
731 
732  protected:
733   template<class> friend class AstNodeFactory;
734 
DoWhileStatement(Isolate * isolate,ZoneStringList * labels)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 
751 class WhileStatement: public IterationStatement {
752  public:
DECLARE_NODE_TYPE(WhileStatement)753   DECLARE_NODE_TYPE(WhileStatement)
754 
755   void Initialize(Expression* cond, Statement* body) {
756     IterationStatement::Initialize(body);
757     cond_ = cond;
758   }
759 
cond()760   Expression* cond() const { return cond_; }
may_have_function_literal()761   bool may_have_function_literal() const {
762     return may_have_function_literal_;
763   }
set_may_have_function_literal(bool value)764   void set_may_have_function_literal(bool value) {
765     may_have_function_literal_ = value;
766   }
767 
768   // Bailout support.
ContinueId()769   virtual int ContinueId() const { return EntryId(); }
StackCheckId()770   virtual int StackCheckId() const { return body_id_; }
BodyId()771   int BodyId() const { return body_id_; }
772 
773  protected:
774   template<class> friend class AstNodeFactory;
775 
WhileStatement(Isolate * isolate,ZoneStringList * labels)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 
791 class ForStatement: public IterationStatement {
792  public:
DECLARE_NODE_TYPE(ForStatement)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 
init()805   Statement* init() const { return init_; }
cond()806   Expression* cond() const { return cond_; }
next()807   Statement* next() const { return next_; }
808 
may_have_function_literal()809   bool may_have_function_literal() const {
810     return may_have_function_literal_;
811   }
set_may_have_function_literal(bool value)812   void set_may_have_function_literal(bool value) {
813     may_have_function_literal_ = value;
814   }
815 
816   // Bailout support.
ContinueId()817   virtual int ContinueId() const { return continue_id_; }
StackCheckId()818   virtual int StackCheckId() const { return body_id_; }
BodyId()819   int BodyId() const { return body_id_; }
820 
is_fast_smi_loop()821   bool is_fast_smi_loop() { return loop_variable_ != NULL; }
loop_variable()822   Variable* loop_variable() { return loop_variable_; }
set_loop_variable(Variable * var)823   void set_loop_variable(Variable* var) { loop_variable_ = var; }
824 
825  protected:
826   template<class> friend class AstNodeFactory;
827 
ForStatement(Isolate * isolate,ZoneStringList * labels)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 
851 class ForInStatement: public IterationStatement {
852  public:
DECLARE_NODE_TYPE(ForInStatement)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 
each()861   Expression* each() const { return each_; }
enumerable()862   Expression* enumerable() const { return enumerable_; }
863 
ContinueId()864   virtual int ContinueId() const { return EntryId(); }
StackCheckId()865   virtual int StackCheckId() const { return body_id_; }
BodyId()866   int BodyId() const { return body_id_; }
PrepareId()867   int PrepareId() const { return prepare_id_; }
868 
869  protected:
870   template<class> friend class AstNodeFactory;
871 
ForInStatement(Isolate * isolate,ZoneStringList * labels)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 
888 class ExpressionStatement: public Statement {
889  public:
DECLARE_NODE_TYPE(ExpressionStatement)890   DECLARE_NODE_TYPE(ExpressionStatement)
891 
892   void set_expression(Expression* e) { expression_ = e; }
expression()893   Expression* expression() const { return expression_; }
894 
895  protected:
896   template<class> friend class AstNodeFactory;
897 
ExpressionStatement(Expression * expression)898   explicit ExpressionStatement(Expression* expression)
899       : expression_(expression) { }
900 
901  private:
902   Expression* expression_;
903 };
904 
905 
906 class ContinueStatement: public Statement {
907  public:
DECLARE_NODE_TYPE(ContinueStatement)908   DECLARE_NODE_TYPE(ContinueStatement)
909 
910   IterationStatement* target() const { return target_; }
911 
912  protected:
913   template<class> friend class AstNodeFactory;
914 
ContinueStatement(IterationStatement * target)915   explicit ContinueStatement(IterationStatement* target)
916       : target_(target) { }
917 
918  private:
919   IterationStatement* target_;
920 };
921 
922 
923 class BreakStatement: public Statement {
924  public:
DECLARE_NODE_TYPE(BreakStatement)925   DECLARE_NODE_TYPE(BreakStatement)
926 
927   BreakableStatement* target() const { return target_; }
928 
929  protected:
930   template<class> friend class AstNodeFactory;
931 
BreakStatement(BreakableStatement * target)932   explicit BreakStatement(BreakableStatement* target)
933       : target_(target) { }
934 
935  private:
936   BreakableStatement* target_;
937 };
938 
939 
940 class ReturnStatement: public Statement {
941  public:
DECLARE_NODE_TYPE(ReturnStatement)942   DECLARE_NODE_TYPE(ReturnStatement)
943 
944   Expression* expression() const { return expression_; }
945 
946  protected:
947   template<class> friend class AstNodeFactory;
948 
ReturnStatement(Expression * expression)949   explicit ReturnStatement(Expression* expression)
950       : expression_(expression) { }
951 
952  private:
953   Expression* expression_;
954 };
955 
956 
957 class WithStatement: public Statement {
958  public:
DECLARE_NODE_TYPE(WithStatement)959   DECLARE_NODE_TYPE(WithStatement)
960 
961   Expression* expression() const { return expression_; }
statement()962   Statement* statement() const { return statement_; }
963 
964  protected:
965   template<class> friend class AstNodeFactory;
966 
WithStatement(Expression * expression,Statement * statement)967   WithStatement(Expression* expression, Statement* statement)
968       : expression_(expression),
969         statement_(statement) { }
970 
971  private:
972   Expression* expression_;
973   Statement* statement_;
974 };
975 
976 
977 class CaseClause: public ZoneObject {
978  public:
979   CaseClause(Isolate* isolate,
980              Expression* label,
981              ZoneList<Statement*>* statements,
982              int pos);
983 
is_default()984   bool is_default() const { return label_ == NULL; }
label()985   Expression* label() const {
986     CHECK(!is_default());
987     return label_;
988   }
body_target()989   Label* body_target() { return &body_target_; }
statements()990   ZoneList<Statement*>* statements() const { return statements_; }
991 
position()992   int position() const { return position_; }
set_position(int pos)993   void set_position(int pos) { position_ = pos; }
994 
EntryId()995   int EntryId() { return entry_id_; }
CompareId()996   int CompareId() { return compare_id_; }
997 
998   // Type feedback information.
999   void RecordTypeFeedback(TypeFeedbackOracle* oracle);
IsSmiCompare()1000   bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
IsSymbolCompare()1001   bool IsSymbolCompare() { return compare_type_ == SYMBOL_ONLY; }
IsStringCompare()1002   bool IsStringCompare() { return compare_type_ == STRING_ONLY; }
IsObjectCompare()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 
1023 class SwitchStatement: public BreakableStatement {
1024  public:
DECLARE_NODE_TYPE(SwitchStatement)1025   DECLARE_NODE_TYPE(SwitchStatement)
1026 
1027   void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) {
1028     tag_ = tag;
1029     cases_ = cases;
1030   }
1031 
tag()1032   Expression* tag() const { return tag_; }
cases()1033   ZoneList<CaseClause*>* cases() const { return cases_; }
1034 
1035  protected:
1036   template<class> friend class AstNodeFactory;
1037 
SwitchStatement(Isolate * isolate,ZoneStringList * labels)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.
1054 class IfStatement: public Statement {
1055  public:
DECLARE_NODE_TYPE(IfStatement)1056   DECLARE_NODE_TYPE(IfStatement)
1057 
1058   bool HasThenStatement() const { return !then_statement()->IsEmpty(); }
HasElseStatement()1059   bool HasElseStatement() const { return !else_statement()->IsEmpty(); }
1060 
condition()1061   Expression* condition() const { return condition_; }
then_statement()1062   Statement* then_statement() const { return then_statement_; }
else_statement()1063   Statement* else_statement() const { return else_statement_; }
1064 
IfId()1065   int IfId() const { return if_id_; }
ThenId()1066   int ThenId() const { return then_id_; }
ElseId()1067   int ElseId() const { return else_id_; }
1068 
1069  protected:
1070   template<class> friend class AstNodeFactory;
1071 
IfStatement(Isolate * isolate,Expression * condition,Statement * then_statement,Statement * else_statement)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.
1096 class TargetCollector: public AstNode {
1097  public:
TargetCollector()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.
Accept(AstVisitor * v)1106   virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
AsTargetCollector()1107   virtual TargetCollector* AsTargetCollector() { return this; }
1108 
targets()1109   ZoneList<Label*>* targets() { return &targets_; }
1110 
1111  private:
1112   ZoneList<Label*> targets_;
1113 };
1114 
1115 
1116 class TryStatement: public Statement {
1117  public:
set_escaping_targets(ZoneList<Label * > * targets)1118   void set_escaping_targets(ZoneList<Label*>* targets) {
1119     escaping_targets_ = targets;
1120   }
1121 
index()1122   int index() const { return index_; }
try_block()1123   Block* try_block() const { return try_block_; }
escaping_targets()1124   ZoneList<Label*>* escaping_targets() const { return escaping_targets_; }
1125 
1126  protected:
TryStatement(int index,Block * try_block)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 
1141 class TryCatchStatement: public TryStatement {
1142  public:
DECLARE_NODE_TYPE(TryCatchStatement)1143   DECLARE_NODE_TYPE(TryCatchStatement)
1144 
1145   Scope* scope() { return scope_; }
variable()1146   Variable* variable() { return variable_; }
catch_block()1147   Block* catch_block() const { return catch_block_; }
1148 
1149  protected:
1150   template<class> friend class AstNodeFactory;
1151 
TryCatchStatement(int index,Block * try_block,Scope * scope,Variable * variable,Block * catch_block)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 
1170 class TryFinallyStatement: public TryStatement {
1171  public:
DECLARE_NODE_TYPE(TryFinallyStatement)1172   DECLARE_NODE_TYPE(TryFinallyStatement)
1173 
1174   Block* finally_block() const { return finally_block_; }
1175 
1176  protected:
1177   template<class> friend class AstNodeFactory;
1178 
TryFinallyStatement(int index,Block * try_block,Block * finally_block)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 
1188 class DebuggerStatement: public Statement {
1189  public:
1190   DECLARE_NODE_TYPE(DebuggerStatement)
1191 
1192  protected:
1193   template<class> friend class AstNodeFactory;
1194 
DebuggerStatement()1195   DebuggerStatement() {}
1196 };
1197 
1198 
1199 class EmptyStatement: public Statement {
1200  public:
1201   DECLARE_NODE_TYPE(EmptyStatement)
1202 
1203  protected:
1204   template<class> friend class AstNodeFactory;
1205 
EmptyStatement()1206   EmptyStatement() {}
1207 };
1208 
1209 
1210 class Literal: public Expression {
1211  public:
DECLARE_NODE_TYPE(Literal)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 
AsPropertyName()1222   Handle<String> AsPropertyName() {
1223     ASSERT(IsPropertyName());
1224     return Handle<String>::cast(handle_);
1225   }
1226 
ToBooleanIsTrue()1227   virtual bool ToBooleanIsTrue() { return handle_->ToBoolean()->IsTrue(); }
ToBooleanIsFalse()1228   virtual bool ToBooleanIsFalse() { return handle_->ToBoolean()->IsFalse(); }
1229 
1230   // Identity testers.
IsNull()1231   bool IsNull() const {
1232     ASSERT(!handle_.is_null());
1233     return handle_->IsNull();
1234   }
IsTrue()1235   bool IsTrue() const {
1236     ASSERT(!handle_.is_null());
1237     return handle_->IsTrue();
1238   }
IsFalse()1239   bool IsFalse() const {
1240     ASSERT(!handle_.is_null());
1241     return handle_->IsFalse();
1242   }
1243 
handle()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!
Hash()1248   uint32_t Hash() { return ToString()->Hash(); }
1249 
Match(void * literal1,void * literal2)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 
Literal(Isolate * isolate,Handle<Object> handle)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.
1271 class MaterializedLiteral: public Expression {
1272  public:
AsMaterializedLiteral()1273   virtual MaterializedLiteral* AsMaterializedLiteral() { return this; }
1274 
literal_index()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.
is_simple()1279   bool is_simple() const { return is_simple_; }
1280 
depth()1281   int depth() const { return depth_; }
1282 
1283  protected:
MaterializedLiteral(Isolate * isolate,int literal_index,bool is_simple,int depth)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.
1302 class 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 
key()1319     Literal* key() { return key_; }
value()1320     Expression* value() { return value_; }
kind()1321     Kind kind() { return kind_; }
1322 
1323     // Type feedback information.
1324     void RecordTypeFeedback(TypeFeedbackOracle* oracle);
IsMonomorphic()1325     bool IsMonomorphic() { return !receiver_type_.is_null(); }
GetReceiverType()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);
set_key(Literal * key)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 
DECLARE_NODE_TYPE(ObjectLiteral)1347   DECLARE_NODE_TYPE(ObjectLiteral)
1348 
1349   Handle<FixedArray> constant_properties() const {
1350     return constant_properties_;
1351   }
properties()1352   ZoneList<Property*>* properties() const { return properties_; }
1353 
fast_elements()1354   bool fast_elements() const { return fast_elements_; }
1355 
has_function()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 {
AccessorsAccessors1370     Accessors() : getter(NULL), setter(NULL) { }
1371     Expression* getter;
1372     Expression* setter;
1373   };
1374 
1375  protected:
1376   template<class> friend class AstNodeFactory;
1377 
ObjectLiteral(Isolate * isolate,Handle<FixedArray> constant_properties,ZoneList<Property * > * properties,int literal_index,bool is_simple,bool fast_elements,int depth,bool has_function)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.
1401 class RegExpLiteral: public MaterializedLiteral {
1402  public:
DECLARE_NODE_TYPE(RegExpLiteral)1403   DECLARE_NODE_TYPE(RegExpLiteral)
1404 
1405   Handle<String> pattern() const { return pattern_; }
flags()1406   Handle<String> flags() const { return flags_; }
1407 
1408  protected:
1409   template<class> friend class AstNodeFactory;
1410 
RegExpLiteral(Isolate * isolate,Handle<String> pattern,Handle<String> flags,int literal_index)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.
1426 class ArrayLiteral: public MaterializedLiteral {
1427  public:
DECLARE_NODE_TYPE(ArrayLiteral)1428   DECLARE_NODE_TYPE(ArrayLiteral)
1429 
1430   Handle<FixedArray> constant_elements() const { return constant_elements_; }
values()1431   ZoneList<Expression*>* values() const { return values_; }
1432 
1433   // Return an AST id for an element that is used in simulate instructions.
GetIdForElement(int i)1434   int GetIdForElement(int i) { return first_element_id_ + i; }
1435 
1436  protected:
1437   template<class> friend class AstNodeFactory;
1438 
ArrayLiteral(Isolate * isolate,Handle<FixedArray> constant_elements,ZoneList<Expression * > * values,int literal_index,bool is_simple,int depth)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 
1457 class VariableProxy: public Expression {
1458  public:
DECLARE_NODE_TYPE(VariableProxy)1459   DECLARE_NODE_TYPE(VariableProxy)
1460 
1461   virtual bool IsValidLeftHandSide() {
1462     return var_ == NULL ? true : var_->IsValidLeftHandSide();
1463   }
1464 
IsVariable(Handle<String> n)1465   bool IsVariable(Handle<String> n) {
1466     return !is_this() && name().is_identical_to(n);
1467   }
1468 
IsArguments()1469   bool IsArguments() { return var_ != NULL && var_->is_arguments(); }
1470 
IsLValue()1471   bool IsLValue() {
1472     return is_lvalue_;
1473   }
1474 
name()1475   Handle<String> name() const { return name_; }
var()1476   Variable* var() const { return var_; }
is_this()1477   bool is_this() const { return is_this_; }
position()1478   int position() const { return position_; }
interface()1479   Interface* interface() const { return interface_; }
1480 
1481 
MarkAsTrivial()1482   void MarkAsTrivial() { is_trivial_ = true; }
MarkAsLValue()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 
1511 class Property: public Expression {
1512  public:
DECLARE_NODE_TYPE(Property)1513   DECLARE_NODE_TYPE(Property)
1514 
1515   virtual bool IsValidLeftHandSide() { return true; }
1516 
obj()1517   Expression* obj() const { return obj_; }
key()1518   Expression* key() const { return key_; }
position()1519   virtual int position() const { return pos_; }
1520 
IsStringLength()1521   bool IsStringLength() const { return is_string_length_; }
IsStringAccess()1522   bool IsStringAccess() const { return is_string_access_; }
IsFunctionPrototype()1523   bool IsFunctionPrototype() const { return is_function_prototype_; }
1524 
1525   // Type feedback information.
1526   void RecordTypeFeedback(TypeFeedbackOracle* oracle);
IsMonomorphic()1527   virtual bool IsMonomorphic() { return is_monomorphic_; }
GetReceiverTypes()1528   virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
IsArrayLength()1529   bool IsArrayLength() { return is_array_length_; }
IsUninitialized()1530   bool IsUninitialized() { return is_uninitialized_; }
1531 
1532  protected:
1533   template<class> friend class AstNodeFactory;
1534 
Property(Isolate * isolate,Expression * obj,Expression * key,int pos)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 
1565 class Call: public Expression {
1566  public:
DECLARE_NODE_TYPE(Call)1567   DECLARE_NODE_TYPE(Call)
1568 
1569   Expression* expression() const { return expression_; }
arguments()1570   ZoneList<Expression*>* arguments() const { return arguments_; }
position()1571   virtual int position() const { return pos_; }
1572 
1573   void RecordTypeFeedback(TypeFeedbackOracle* oracle,
1574                           CallKind call_kind);
GetReceiverTypes()1575   virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
IsMonomorphic()1576   virtual bool IsMonomorphic() { return is_monomorphic_; }
check_type()1577   CheckType check_type() const { return check_type_; }
target()1578   Handle<JSFunction> target() { return target_; }
holder()1579   Handle<JSObject> holder() { return holder_; }
cell()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.
ReturnId()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 
Call(Isolate * isolate,Expression * expression,ZoneList<Expression * > * arguments,int pos)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 
1624 class CallNew: public Expression {
1625  public:
DECLARE_NODE_TYPE(CallNew)1626   DECLARE_NODE_TYPE(CallNew)
1627 
1628   Expression* expression() const { return expression_; }
arguments()1629   ZoneList<Expression*>* arguments() const { return arguments_; }
position()1630   virtual int position() const { return pos_; }
1631 
1632   void RecordTypeFeedback(TypeFeedbackOracle* oracle);
IsMonomorphic()1633   virtual bool IsMonomorphic() { return is_monomorphic_; }
target()1634   Handle<JSFunction> target() { return target_; }
1635 
1636   // Bailout support.
ReturnId()1637   int ReturnId() const { return return_id_; }
1638 
1639  protected:
1640   template<class> friend class AstNodeFactory;
1641 
CallNew(Isolate * isolate,Expression * expression,ZoneList<Expression * > * arguments,int pos)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").
1669 class CallRuntime: public Expression {
1670  public:
DECLARE_NODE_TYPE(CallRuntime)1671   DECLARE_NODE_TYPE(CallRuntime)
1672 
1673   Handle<String> name() const { return name_; }
function()1674   const Runtime::Function* function() const { return function_; }
arguments()1675   ZoneList<Expression*>* arguments() const { return arguments_; }
is_jsruntime()1676   bool is_jsruntime() const { return function_ == NULL; }
1677 
1678  protected:
1679   template<class> friend class AstNodeFactory;
1680 
CallRuntime(Isolate * isolate,Handle<String> name,const Runtime::Function * function,ZoneList<Expression * > * arguments)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 
1697 class UnaryOperation: public Expression {
1698  public:
1699   DECLARE_NODE_TYPE(UnaryOperation)
1700 
1701   virtual bool ResultOverwriteAllowed();
1702 
op()1703   Token::Value op() const { return op_; }
expression()1704   Expression* expression() const { return expression_; }
position()1705   virtual int position() const { return pos_; }
1706 
MaterializeTrueId()1707   int MaterializeTrueId() { return materialize_true_id_; }
MaterializeFalseId()1708   int MaterializeFalseId() { return materialize_false_id_; }
1709 
1710  protected:
1711   template<class> friend class AstNodeFactory;
1712 
UnaryOperation(Isolate * isolate,Token::Value op,Expression * expression,int pos)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 
1742 class BinaryOperation: public Expression {
1743  public:
1744   DECLARE_NODE_TYPE(BinaryOperation)
1745 
1746   virtual bool ResultOverwriteAllowed();
1747 
op()1748   Token::Value op() const { return op_; }
left()1749   Expression* left() const { return left_; }
right()1750   Expression* right() const { return right_; }
position()1751   virtual int position() const { return pos_; }
1752 
1753   // Bailout support.
RightId()1754   int RightId() const { return right_id_; }
1755 
1756  protected:
1757   template<class> friend class AstNodeFactory;
1758 
BinaryOperation(Isolate * isolate,Token::Value op,Expression * left,Expression * right,int pos)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 
1782 class CountOperation: public Expression {
1783  public:
DECLARE_NODE_TYPE(CountOperation)1784   DECLARE_NODE_TYPE(CountOperation)
1785 
1786   bool is_prefix() const { return is_prefix_; }
is_postfix()1787   bool is_postfix() const { return !is_prefix_; }
1788 
op()1789   Token::Value op() const { return op_; }
binary_op()1790   Token::Value binary_op() {
1791     return (op() == Token::INC) ? Token::ADD : Token::SUB;
1792   }
1793 
expression()1794   Expression* expression() const { return expression_; }
position()1795   virtual int position() const { return pos_; }
1796 
MarkAsStatement()1797   virtual void MarkAsStatement() { is_prefix_ = true; }
1798 
1799   void RecordTypeFeedback(TypeFeedbackOracle* oracle);
IsMonomorphic()1800   virtual bool IsMonomorphic() { return is_monomorphic_; }
GetReceiverTypes()1801   virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
1802 
1803   // Bailout support.
AssignmentId()1804   int AssignmentId() const { return assignment_id_; }
CountId()1805   int CountId() const { return count_id_; }
1806 
1807  protected:
1808   template<class> friend class AstNodeFactory;
1809 
CountOperation(Isolate * isolate,Token::Value op,bool is_prefix,Expression * expr,int pos)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 
1835 class CompareOperation: public Expression {
1836  public:
DECLARE_NODE_TYPE(CompareOperation)1837   DECLARE_NODE_TYPE(CompareOperation)
1838 
1839   Token::Value op() const { return op_; }
left()1840   Expression* left() const { return left_; }
right()1841   Expression* right() const { return right_; }
position()1842   virtual int position() const { return pos_; }
1843 
1844   // Type feedback information.
1845   void RecordTypeFeedback(TypeFeedbackOracle* oracle);
IsSmiCompare()1846   bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
IsObjectCompare()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 
CompareOperation(Isolate * isolate,Token::Value op,Expression * left,Expression * right,int pos)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 
1882 class Conditional: public Expression {
1883  public:
DECLARE_NODE_TYPE(Conditional)1884   DECLARE_NODE_TYPE(Conditional)
1885 
1886   Expression* condition() const { return condition_; }
then_expression()1887   Expression* then_expression() const { return then_expression_; }
else_expression()1888   Expression* else_expression() const { return else_expression_; }
1889 
then_expression_position()1890   int then_expression_position() const { return then_expression_position_; }
else_expression_position()1891   int else_expression_position() const { return else_expression_position_; }
1892 
ThenId()1893   int ThenId() const { return then_id_; }
ElseId()1894   int ElseId() const { return else_id_; }
1895 
1896  protected:
1897   template<class> friend class AstNodeFactory;
1898 
Conditional(Isolate * isolate,Expression * condition,Expression * then_expression,Expression * else_expression,int then_expression_position,int else_expression_position)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 
1925 class Assignment: public Expression {
1926  public:
DECLARE_NODE_TYPE(Assignment)1927   DECLARE_NODE_TYPE(Assignment)
1928 
1929   Assignment* AsSimpleAssignment() { return !is_compound() ? this : NULL; }
1930 
1931   Token::Value binary_op() const;
1932 
op()1933   Token::Value op() const { return op_; }
target()1934   Expression* target() const { return target_; }
value()1935   Expression* value() const { return value_; }
position()1936   virtual int position() const { return pos_; }
binary_operation()1937   BinaryOperation* binary_operation() const { return binary_operation_; }
1938 
1939   // This check relies on the definition order of token in token.h.
is_compound()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.
starts_initialization_block()1946   bool starts_initialization_block() { return block_start_; }
ends_initialization_block()1947   bool ends_initialization_block() { return block_end_; }
mark_block_start()1948   void mark_block_start() { block_start_ = true; }
mark_block_end()1949   void mark_block_end() { block_end_ = true; }
1950 
1951   // Type feedback information.
1952   void RecordTypeFeedback(TypeFeedbackOracle* oracle);
IsMonomorphic()1953   virtual bool IsMonomorphic() { return is_monomorphic_; }
GetReceiverTypes()1954   virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
1955 
1956   // Bailout support.
CompoundLoadId()1957   int CompoundLoadId() const { return compound_load_id_; }
AssignmentId()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>
Init(Isolate * isolate,AstNodeFactory<Visitor> * factory)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 
1996 class Throw: public Expression {
1997  public:
DECLARE_NODE_TYPE(Throw)1998   DECLARE_NODE_TYPE(Throw)
1999 
2000   Expression* exception() const { return exception_; }
position()2001   virtual int position() const { return pos_; }
2002 
2003  protected:
2004   template<class> friend class AstNodeFactory;
2005 
Throw(Isolate * isolate,Expression * exception,int pos)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 
2015 class 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 
DECLARE_NODE_TYPE(FunctionLiteral)2033   DECLARE_NODE_TYPE(FunctionLiteral)
2034 
2035   Handle<String> name() const { return name_; }
scope()2036   Scope* scope() const { return scope_; }
body()2037   ZoneList<Statement*>* body() const { return body_; }
set_function_token_position(int pos)2038   void set_function_token_position(int pos) { function_token_position_ = pos; }
function_token_position()2039   int function_token_position() const { return function_token_position_; }
2040   int start_position() const;
2041   int end_position() const;
SourceSize()2042   int SourceSize() const { return end_position() - start_position(); }
is_expression()2043   bool is_expression() const { return IsExpression::decode(bitfield_); }
is_anonymous()2044   bool is_anonymous() const { return IsAnonymous::decode(bitfield_); }
is_classic_mode()2045   bool is_classic_mode() const { return language_mode() == CLASSIC_MODE; }
2046   LanguageMode language_mode() const;
2047 
materialized_literal_count()2048   int materialized_literal_count() { return materialized_literal_count_; }
expected_property_count()2049   int expected_property_count() { return expected_property_count_; }
handler_count()2050   int handler_count() { return handler_count_; }
has_only_simple_this_property_assignments()2051   bool has_only_simple_this_property_assignments() {
2052     return HasOnlySimpleThisPropertyAssignments::decode(bitfield_);
2053   }
this_property_assignments()2054   Handle<FixedArray> this_property_assignments() {
2055       return this_property_assignments_;
2056   }
parameter_count()2057   int parameter_count() { return parameter_count_; }
2058 
2059   bool AllowsLazyCompilation();
2060 
debug_name()2061   Handle<String> debug_name() const {
2062     if (name_->length() > 0) return name_;
2063     return inferred_name();
2064   }
2065 
inferred_name()2066   Handle<String> inferred_name() const { return inferred_name_; }
set_inferred_name(Handle<String> inferred_name)2067   void set_inferred_name(Handle<String> inferred_name) {
2068     inferred_name_ = inferred_name;
2069   }
2070 
pretenure()2071   bool pretenure() { return Pretenure::decode(bitfield_); }
set_pretenure()2072   void set_pretenure() { bitfield_ |= Pretenure::encode(true); }
2073 
has_duplicate_parameters()2074   bool has_duplicate_parameters() {
2075     return HasDuplicateParameters::decode(bitfield_);
2076   }
2077 
is_function()2078   bool is_function() { return IsFunction::decode(bitfield_) == kIsFunction; }
2079 
ast_node_count()2080   int ast_node_count() { return ast_properties_.node_count(); }
flags()2081   AstProperties::Flags* flags() { return ast_properties_.flags(); }
set_ast_properties(AstProperties * ast_properties)2082   void set_ast_properties(AstProperties* ast_properties) {
2083     ast_properties_ = *ast_properties;
2084   }
2085 
2086  protected:
2087   template<class> friend class AstNodeFactory;
2088 
FunctionLiteral(Isolate * isolate,Handle<String> name,Scope * scope,ZoneList<Statement * > * body,int materialized_literal_count,int expected_property_count,int handler_count,bool has_only_simple_this_property_assignments,Handle<FixedArray> this_property_assignments,int parameter_count,Type type,ParameterFlag has_duplicate_parameters,IsFunctionFlag is_function)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 
2147 class SharedFunctionInfoLiteral: public Expression {
2148  public:
DECLARE_NODE_TYPE(SharedFunctionInfoLiteral)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 
SharedFunctionInfoLiteral(Isolate * isolate,Handle<SharedFunctionInfo> shared_function_info)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 
2169 class ThisFunction: public Expression {
2170  public:
2171   DECLARE_NODE_TYPE(ThisFunction)
2172 
2173  protected:
2174   template<class> friend class AstNodeFactory;
2175 
ThisFunction(Isolate * isolate)2176   explicit ThisFunction(Isolate* isolate): Expression(isolate) {}
2177 };
2178 
2179 #undef DECLARE_NODE_TYPE
2180 
2181 
2182 // ----------------------------------------------------------------------------
2183 // Regular expressions
2184 
2185 
2186 class RegExpVisitor BASE_EMBEDDED {
2187  public:
~RegExpVisitor()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 
2196 class RegExpTree: public ZoneObject {
2197  public:
2198   static const int kInfinity = kMaxInt;
~RegExpTree()2199   virtual ~RegExpTree() { }
2200   virtual void* Accept(RegExpVisitor* visitor, void* data) = 0;
2201   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2202                              RegExpNode* on_success) = 0;
IsTextElement()2203   virtual bool IsTextElement() { return false; }
IsAnchoredAtStart()2204   virtual bool IsAnchoredAtStart() { return false; }
IsAnchoredAtEnd()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.
CaptureRegisters()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 
2221 class 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();
min_match()2232   virtual int min_match() { return min_match_; }
max_match()2233   virtual int max_match() { return max_match_; }
alternatives()2234   ZoneList<RegExpTree*>* alternatives() { return alternatives_; }
2235  private:
2236   ZoneList<RegExpTree*>* alternatives_;
2237   int min_match_;
2238   int max_match_;
2239 };
2240 
2241 
2242 class 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();
min_match()2253   virtual int min_match() { return min_match_; }
max_match()2254   virtual int max_match() { return max_match_; }
nodes()2255   ZoneList<RegExpTree*>* nodes() { return nodes_; }
2256  private:
2257   ZoneList<RegExpTree*>* nodes_;
2258   int min_match_;
2259   int max_match_;
2260 };
2261 
2262 
2263 class 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   };
RegExpAssertion(Type type)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();
min_match()2281   virtual int min_match() { return 0; }
max_match()2282   virtual int max_match() { return 0; }
type()2283   Type type() { return type_; }
2284  private:
2285   Type type_;
2286 };
2287 
2288 
2289 class CharacterSet BASE_EMBEDDED {
2290  public:
CharacterSet(uc16 standard_set_type)2291   explicit CharacterSet(uc16 standard_set_type)
2292       : ranges_(NULL),
2293         standard_set_type_(standard_set_type) {}
CharacterSet(ZoneList<CharacterRange> * ranges)2294   explicit CharacterSet(ZoneList<CharacterRange>* ranges)
2295       : ranges_(ranges),
2296         standard_set_type_(0) {}
2297   ZoneList<CharacterRange>* ranges();
standard_set_type()2298   uc16 standard_set_type() { return standard_set_type_; }
set_standard_set_type(uc16 special_set_type)2299   void set_standard_set_type(uc16 special_set_type) {
2300     standard_set_type_ = special_set_type;
2301   }
is_standard()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 
2312 class RegExpCharacterClass: public RegExpTree {
2313  public:
RegExpCharacterClass(ZoneList<CharacterRange> * ranges,bool is_negated)2314   RegExpCharacterClass(ZoneList<CharacterRange>* ranges, bool is_negated)
2315       : set_(ranges),
2316         is_negated_(is_negated) { }
RegExpCharacterClass(uc16 type)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();
IsTextElement()2325   virtual bool IsTextElement() { return true; }
min_match()2326   virtual int min_match() { return 1; }
max_match()2327   virtual int max_match() { return 1; }
2328   virtual void AppendToText(RegExpText* text);
character_set()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
standard_type()2344   uc16 standard_type() { return set_.standard_set_type(); }
ranges()2345   ZoneList<CharacterRange>* ranges() { return set_.ranges(); }
is_negated()2346   bool is_negated() { return is_negated_; }
2347 
2348  private:
2349   CharacterSet set_;
2350   bool is_negated_;
2351 };
2352 
2353 
2354 class RegExpAtom: public RegExpTree {
2355  public:
RegExpAtom(Vector<const uc16> data)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();
IsTextElement()2362   virtual bool IsTextElement() { return true; }
min_match()2363   virtual int min_match() { return data_.length(); }
max_match()2364   virtual int max_match() { return data_.length(); }
2365   virtual void AppendToText(RegExpText* text);
data()2366   Vector<const uc16> data() { return data_; }
length()2367   int length() { return data_.length(); }
2368  private:
2369   Vector<const uc16> data_;
2370 };
2371 
2372 
2373 class RegExpText: public RegExpTree {
2374  public:
RegExpText()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();
IsTextElement()2381   virtual bool IsTextElement() { return true; }
min_match()2382   virtual int min_match() { return length_; }
max_match()2383   virtual int max_match() { return length_; }
2384   virtual void AppendToText(RegExpText* text);
AddElement(TextElement elm)2385   void AddElement(TextElement elm)  {
2386     elements_.Add(elm);
2387     length_ += elm.length();
2388   }
elements()2389   ZoneList<TextElement>* elements() { return &elements_; }
2390  private:
2391   ZoneList<TextElement> elements_;
2392   int length_;
2393 };
2394 
2395 
2396 class RegExpQuantifier: public RegExpTree {
2397  public:
2398   enum Type { GREEDY, NON_GREEDY, POSSESSIVE };
RegExpQuantifier(int min,int max,Type type,RegExpTree * body)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();
min_match()2424   virtual int min_match() { return min_match_; }
max_match()2425   virtual int max_match() { return max_match_; }
min()2426   int min() { return min_; }
max()2427   int max() { return max_; }
is_possessive()2428   bool is_possessive() { return type_ == POSSESSIVE; }
is_non_greedy()2429   bool is_non_greedy() { return type_ == NON_GREEDY; }
is_greedy()2430   bool is_greedy() { return type_ == GREEDY; }
body()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 
2443 class RegExpCapture: public RegExpTree {
2444  public:
RegExpCapture(RegExpTree * body,int index)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();
min_match()2459   virtual int min_match() { return body_->min_match(); }
max_match()2460   virtual int max_match() { return body_->max_match(); }
body()2461   RegExpTree* body() { return body_; }
index()2462   int index() { return index_; }
StartRegister(int index)2463   static int StartRegister(int index) { return index * 2; }
EndRegister(int index)2464   static int EndRegister(int index) { return index * 2 + 1; }
2465 
2466  private:
2467   RegExpTree* body_;
2468   int index_;
2469 };
2470 
2471 
2472 class RegExpLookahead: public RegExpTree {
2473  public:
RegExpLookahead(RegExpTree * body,bool is_positive,int capture_count,int capture_from)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();
min_match()2490   virtual int min_match() { return 0; }
max_match()2491   virtual int max_match() { return 0; }
body()2492   RegExpTree* body() { return body_; }
is_positive()2493   bool is_positive() { return is_positive_; }
capture_count()2494   int capture_count() { return capture_count_; }
capture_from()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 
2505 class RegExpBackReference: public RegExpTree {
2506  public:
RegExpBackReference(RegExpCapture * capture)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();
min_match()2514   virtual int min_match() { return 0; }
max_match()2515   virtual int max_match() { return capture_->max_match(); }
index()2516   int index() { return capture_->index(); }
capture()2517   RegExpCapture* capture() { return capture_; }
2518  private:
2519   RegExpCapture* capture_;
2520 };
2521 
2522 
2523 class RegExpEmpty: public RegExpTree {
2524  public:
RegExpEmpty()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();
min_match()2531   virtual int min_match() { return 0; }
max_match()2532   virtual int max_match() { return 0; }
GetInstance()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 
ModuleVariable(VariableProxy * proxy)2543 inline 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 
2553 class AstVisitor BASE_EMBEDDED {
2554  public:
AstVisitor()2555   AstVisitor() : isolate_(Isolate::Current()), stack_overflow_(false) { }
~AstVisitor()2556   virtual ~AstVisitor() { }
2557 
2558   // Stack overflow check and dynamic dispatch.
Visit(AstNode * node)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.
HasStackOverflow()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.
SetStackOverflow()2573   void SetStackOverflow() { stack_overflow_ = true; }
ClearStackOverflow()2574   void ClearStackOverflow() { stack_overflow_ = false; }
2575 
2576   // Individual AST nodes.
2577 #define DEF_VISIT(type)                         \
2578   virtual void Visit##type(type* node) = 0;
AST_NODE_LIST(DEF_VISIT)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 
2594 class AstConstructionVisitor BASE_EMBEDDED {
2595  public:
AstConstructionVisitor()2596   AstConstructionVisitor() { }
2597 
ast_properties()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);
AST_NODE_LIST(DEF_VISIT)2606   AST_NODE_LIST(DEF_VISIT)
2607 #undef DEF_VISIT
2608 
2609   void increase_node_count() { properties_.add_node_count(1); }
add_flag(AstPropertiesFlag flag)2610   void add_flag(AstPropertiesFlag flag) { properties_.flags()->Add(flag); }
2611 
2612   AstProperties properties_;
2613 };
2614 
2615 
2616 class 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 
2630 template<class Visitor>
2631 class AstNodeFactory BASE_EMBEDDED {
2632  public:
AstNodeFactory(Isolate * isolate)2633   explicit AstNodeFactory(Isolate* isolate)
2634       : isolate_(isolate),
2635         zone_(isolate_->zone()) { }
2636 
visitor()2637   Visitor* visitor() { return &visitor_; }
2638 
2639 #define VISIT_AND_RETURN(NodeType, node) \
2640   visitor_.Visit##NodeType((node)); \
2641   return node;
2642 
NewVariableDeclaration(VariableProxy * proxy,VariableMode mode,Scope * scope)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 
NewFunctionDeclaration(VariableProxy * proxy,VariableMode mode,FunctionLiteral * fun,Scope * scope)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 
NewModuleDeclaration(VariableProxy * proxy,Module * module,Scope * scope)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 
NewImportDeclaration(VariableProxy * proxy,Module * module,Scope * scope)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 
NewExportDeclaration(VariableProxy * proxy,Scope * scope)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 
NewModuleLiteral(Block * body,Interface * interface)2683   ModuleLiteral* NewModuleLiteral(Block* body, Interface* interface) {
2684     ModuleLiteral* module = new(zone_) ModuleLiteral(body, interface);
2685     VISIT_AND_RETURN(ModuleLiteral, module)
2686   }
2687 
NewModuleVariable(VariableProxy * proxy)2688   ModuleVariable* NewModuleVariable(VariableProxy* proxy) {
2689     ModuleVariable* module = new(zone_) ModuleVariable(proxy);
2690     VISIT_AND_RETURN(ModuleVariable, module)
2691   }
2692 
NewModulePath(Module * origin,Handle<String> name)2693   ModulePath* NewModulePath(Module* origin, Handle<String> name) {
2694     ModulePath* module = new(zone_) ModulePath(origin, name);
2695     VISIT_AND_RETURN(ModulePath, module)
2696   }
2697 
NewModuleUrl(Handle<String> url)2698   ModuleUrl* NewModuleUrl(Handle<String> url) {
2699     ModuleUrl* module = new(zone_) ModuleUrl(url);
2700     VISIT_AND_RETURN(ModuleUrl, module)
2701   }
2702 
NewBlock(ZoneStringList * labels,int capacity,bool is_initializer_block)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)
STATEMENT_WITH_LABELS(WhileStatement)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 
NewContinueStatement(IterationStatement * target)2728   ContinueStatement* NewContinueStatement(IterationStatement* target) {
2729     ContinueStatement* stmt = new(zone_) ContinueStatement(target);
2730     VISIT_AND_RETURN(ContinueStatement, stmt)
2731   }
2732 
NewBreakStatement(BreakableStatement * target)2733   BreakStatement* NewBreakStatement(BreakableStatement* target) {
2734     BreakStatement* stmt = new(zone_) BreakStatement(target);
2735     VISIT_AND_RETURN(BreakStatement, stmt)
2736   }
2737 
NewReturnStatement(Expression * expression)2738   ReturnStatement* NewReturnStatement(Expression* expression) {
2739     ReturnStatement* stmt = new(zone_) ReturnStatement(expression);
2740     VISIT_AND_RETURN(ReturnStatement, stmt)
2741   }
2742 
NewWithStatement(Expression * expression,Statement * statement)2743   WithStatement* NewWithStatement(Expression* expression,
2744                                   Statement* statement) {
2745     WithStatement* stmt = new(zone_) WithStatement(expression, statement);
2746     VISIT_AND_RETURN(WithStatement, stmt)
2747   }
2748 
NewIfStatement(Expression * condition,Statement * then_statement,Statement * else_statement)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 
NewTryCatchStatement(int index,Block * try_block,Scope * scope,Variable * variable,Block * catch_block)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 
NewTryFinallyStatement(int index,Block * try_block,Block * finally_block)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 
NewDebuggerStatement()2775   DebuggerStatement* NewDebuggerStatement() {
2776     DebuggerStatement* stmt = new(zone_) DebuggerStatement();
2777     VISIT_AND_RETURN(DebuggerStatement, stmt)
2778   }
2779 
NewEmptyStatement()2780   EmptyStatement* NewEmptyStatement() {
2781     return new(zone_) EmptyStatement();
2782   }
2783 
NewLiteral(Handle<Object> handle)2784   Literal* NewLiteral(Handle<Object> handle) {
2785     Literal* lit = new(zone_) Literal(isolate_, handle);
2786     VISIT_AND_RETURN(Literal, lit)
2787   }
2788 
NewNumberLiteral(double number)2789   Literal* NewNumberLiteral(double number) {
2790     return NewLiteral(isolate_->factory()->NewNumber(number, TENURED));
2791   }
2792 
NewObjectLiteral(Handle<FixedArray> constant_properties,ZoneList<ObjectLiteral::Property * > * properties,int literal_index,bool is_simple,bool fast_elements,int depth,bool has_function)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 
NewObjectLiteralProperty(bool is_getter,FunctionLiteral * value)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 
NewRegExpLiteral(Handle<String> pattern,Handle<String> flags,int literal_index)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 
NewArrayLiteral(Handle<FixedArray> constant_elements,ZoneList<Expression * > * values,int literal_index,bool is_simple,int depth)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 
NewVariableProxy(Variable * var)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 
NewProperty(Expression * obj,Expression * key,int pos)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 
NewCall(Expression * expression,ZoneList<Expression * > * arguments,int pos)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 
NewCallNew(Expression * expression,ZoneList<Expression * > * arguments,int pos)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 
NewCallRuntime(Handle<String> name,const Runtime::Function * function,ZoneList<Expression * > * arguments)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 
NewUnaryOperation(Token::Value op,Expression * expression,int pos)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 
NewBinaryOperation(Token::Value op,Expression * left,Expression * right,int pos)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 
NewCountOperation(Token::Value op,bool is_prefix,Expression * expr,int pos)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 
NewCompareOperation(Token::Value op,Expression * left,Expression * right,int pos)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 
NewConditional(Expression * condition,Expression * then_expression,Expression * else_expression,int then_expression_position,int else_expression_position)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 
NewAssignment(Token::Value op,Expression * target,Expression * value,int pos)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 
NewThrow(Expression * exception,int pos)2931   Throw* NewThrow(Expression* exception, int pos) {
2932     Throw* t = new(zone_) Throw(isolate_, exception, pos);
2933     VISIT_AND_RETURN(Throw, t)
2934   }
2935 
NewFunctionLiteral(Handle<String> name,Scope * scope,ZoneList<Statement * > * body,int materialized_literal_count,int expected_property_count,int handler_count,bool has_only_simple_this_property_assignments,Handle<FixedArray> this_property_assignments,int parameter_count,FunctionLiteral::ParameterFlag has_duplicate_parameters,FunctionLiteral::Type type,FunctionLiteral::IsFunctionFlag is_function)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 
NewSharedFunctionInfoLiteral(Handle<SharedFunctionInfo> shared_function_info)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 
NewThisFunction()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