Chromium Code Reviews| Index: src/ast.h | 
| diff --git a/src/ast.h b/src/ast.h | 
| index 34fadab62d8ec52949ab352a97051ad7ad6ae4f1..faee31c1f6363c9ece416937f645ac6bb7e9030d 100644 | 
| --- a/src/ast.h | 
| +++ b/src/ast.h | 
| @@ -39,6 +39,7 @@ | 
| #include "small-pointer-list.h" | 
| #include "smart-array-pointer.h" | 
| #include "token.h" | 
| +#include "utils.h" | 
| #include "variables.h" | 
| #include "zone-inl.h" | 
| @@ -103,6 +104,8 @@ namespace internal { | 
| EXPRESSION_NODE_LIST(V) | 
| // Forward declarations | 
| +class AstConstructionVisitor; | 
| +template<class> class AstNodeFactory; | 
| class AstVisitor; | 
| class BreakableStatement; | 
| class Expression; | 
| @@ -136,6 +139,44 @@ typedef ZoneList<Handle<String> > ZoneStringList; | 
| typedef ZoneList<Handle<Object> > ZoneObjectList; | 
| +#define DECLARE_NODE_TYPE(type) \ | 
| + virtual void Accept(AstVisitor* v); \ | 
| + virtual AstNode::Type node_type() const { return AstNode::k##type; } \ | 
| + | 
| + | 
| +enum AstPropertiesFlag { | 
| + kDontCrankshaft, | 
| 
 
Kevin Millikin (Chromium)
2012/02/08 09:13:18
To be pedantic (everybody loves that), "Crankshaft
 
Jakob Kummerow
2012/02/08 09:51:02
Done.
 
 | 
| + kDontInline, | 
| + kDontSelfOptimize, | 
| + kDontSoftInline | 
| +}; | 
| + | 
| + | 
| +class AstProperties BASE_EMBEDDED { | 
| + public: | 
| + class Flags : public EnumSet<AstPropertiesFlag, int> {}; | 
| + | 
| + AstProperties() : node_count_(0) { } | 
| + | 
| + explicit AstProperties(const AstProperties& other) | 
| 
 
Kevin Millikin (Chromium)
2012/02/08 09:13:18
Default copy constructor and assignment operator s
 
Jakob Kummerow
2012/02/08 09:51:02
Done.
 
 | 
| + : flags_(other.flags_), | 
| + node_count_(other.node_count_) { } | 
| + | 
| + void operator=(const AstProperties& other) { | 
| + flags_ = other.flags_; | 
| + node_count_ = other.node_count_; | 
| + } | 
| + | 
| + Flags* flags() { return &flags_; } | 
| + int node_count() { return node_count_; } | 
| + void add_node_count(int count) { node_count_ += count; } | 
| + | 
| + private: | 
| + Flags flags_; | 
| + int node_count_; | 
| +}; | 
| + | 
| + | 
| class AstNode: public ZoneObject { | 
| public: | 
| #define DECLARE_TYPE_ENUM(type) k##type, | 
| @@ -152,14 +193,11 @@ class AstNode: public ZoneObject { | 
| // that emit code (function declarations). | 
| static const int kDeclarationsId = 3; | 
| - // Override ZoneObject's new to count allocated AST nodes. | 
| void* operator new(size_t size, Zone* zone) { | 
| - Isolate* isolate = zone->isolate(); | 
| - isolate->set_ast_node_count(isolate->ast_node_count() + 1); | 
| return zone->New(static_cast<int>(size)); | 
| } | 
| - AstNode() {} | 
| + AstNode() { } | 
| virtual ~AstNode() { } | 
| @@ -180,19 +218,15 @@ class AstNode: public ZoneObject { | 
| virtual IterationStatement* AsIterationStatement() { return NULL; } | 
| virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; } | 
| - // True if the node is simple enough for us to inline calls containing it. | 
| - virtual bool IsInlineable() const = 0; | 
| - | 
| - static int Count() { return Isolate::Current()->ast_node_count(); } | 
| static void ResetIds() { Isolate::Current()->set_ast_node_id(0); } | 
| protected: | 
| - static unsigned GetNextId(Isolate* isolate) { | 
| + static int GetNextId(Isolate* isolate) { | 
| return ReserveIdRange(isolate, 1); | 
| } | 
| - static unsigned ReserveIdRange(Isolate* isolate, int n) { | 
| - unsigned tmp = isolate->ast_node_id(); | 
| + static int ReserveIdRange(Isolate* isolate, int n) { | 
| + int tmp = isolate->ast_node_id(); | 
| isolate->set_ast_node_id(tmp + n); | 
| return tmp; | 
| } | 
| @@ -326,8 +360,8 @@ class Expression: public AstNode { | 
| unsigned test_id() const { return test_id_; } | 
| private: | 
| - unsigned id_; | 
| - unsigned test_id_; | 
| + int id_; | 
| + int test_id_; | 
| }; | 
| @@ -376,21 +410,8 @@ class BreakableStatement: public Statement { | 
| class Block: public BreakableStatement { | 
| public: | 
| - Block(Isolate* isolate, | 
| - ZoneStringList* labels, | 
| - int capacity, | 
| - bool is_initializer_block) | 
| - : BreakableStatement(isolate, labels, TARGET_FOR_NAMED_ONLY), | 
| - statements_(capacity), | 
| - is_initializer_block_(is_initializer_block), | 
| - block_scope_(NULL) { | 
| - } | 
| - | 
| - | 
| DECLARE_NODE_TYPE(Block) | 
| - virtual bool IsInlineable() const; | 
| - | 
| void AddStatement(Statement* statement) { statements_.Add(statement); } | 
| ZoneList<Statement*>* statements() { return &statements_; } | 
| @@ -399,6 +420,19 @@ class Block: public BreakableStatement { | 
| Scope* block_scope() const { return block_scope_; } | 
| void set_block_scope(Scope* block_scope) { block_scope_ = block_scope; } | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| + Block(Isolate* isolate, | 
| + ZoneStringList* labels, | 
| + int capacity, | 
| + bool is_initializer_block) | 
| + : BreakableStatement(isolate, labels, TARGET_FOR_NAMED_ONLY), | 
| + statements_(capacity), | 
| + is_initializer_block_(is_initializer_block), | 
| + block_scope_(NULL) { | 
| + } | 
| + | 
| private: | 
| ZoneList<Statement*> statements_; | 
| bool is_initializer_block_; | 
| @@ -408,6 +442,17 @@ class Block: public BreakableStatement { | 
| class Declaration: public AstNode { | 
| public: | 
| + DECLARE_NODE_TYPE(Declaration) | 
| + | 
| + VariableProxy* proxy() const { return proxy_; } | 
| + VariableMode mode() const { return mode_; } | 
| + FunctionLiteral* fun() const { return fun_; } // may be NULL | 
| + bool IsInlineable() const; | 
| + Scope* scope() const { return scope_; } | 
| + | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| Declaration(VariableProxy* proxy, | 
| VariableMode mode, | 
| FunctionLiteral* fun, | 
| @@ -424,14 +469,6 @@ class Declaration: public AstNode { | 
| ASSERT(fun == NULL || mode == VAR || mode == LET); | 
| } | 
| - DECLARE_NODE_TYPE(Declaration) | 
| - | 
| - VariableProxy* proxy() const { return proxy_; } | 
| - VariableMode mode() const { return mode_; } | 
| - FunctionLiteral* fun() const { return fun_; } // may be NULL | 
| - virtual bool IsInlineable() const; | 
| - Scope* scope() const { return scope_; } | 
| - | 
| private: | 
| VariableProxy* proxy_; | 
| VariableMode mode_; | 
| @@ -477,14 +514,6 @@ class IterationStatement: public BreakableStatement { | 
| class DoWhileStatement: public IterationStatement { | 
| public: | 
| - DoWhileStatement(Isolate* isolate, ZoneStringList* labels) | 
| - : IterationStatement(isolate, labels), | 
| - cond_(NULL), | 
| - condition_position_(-1), | 
| - continue_id_(GetNextId(isolate)), | 
| - back_edge_id_(GetNextId(isolate)) { | 
| - } | 
| - | 
| DECLARE_NODE_TYPE(DoWhileStatement) | 
| void Initialize(Expression* cond, Statement* body) { | 
| @@ -504,7 +533,16 @@ class DoWhileStatement: public IterationStatement { | 
| virtual int StackCheckId() const { return back_edge_id_; } | 
| int BackEdgeId() const { return back_edge_id_; } | 
| - virtual bool IsInlineable() const; | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| + DoWhileStatement(Isolate* isolate, ZoneStringList* labels) | 
| + : IterationStatement(isolate, labels), | 
| + cond_(NULL), | 
| + condition_position_(-1), | 
| + continue_id_(GetNextId(isolate)), | 
| + back_edge_id_(GetNextId(isolate)) { | 
| + } | 
| private: | 
| Expression* cond_; | 
| @@ -516,13 +554,6 @@ class DoWhileStatement: public IterationStatement { | 
| class WhileStatement: public IterationStatement { | 
| public: | 
| - WhileStatement(Isolate* isolate, ZoneStringList* labels) | 
| - : IterationStatement(isolate, labels), | 
| - cond_(NULL), | 
| - may_have_function_literal_(true), | 
| - body_id_(GetNextId(isolate)) { | 
| - } | 
| - | 
| DECLARE_NODE_TYPE(WhileStatement) | 
| void Initialize(Expression* cond, Statement* body) { | 
| @@ -537,13 +568,22 @@ class WhileStatement: public IterationStatement { | 
| void set_may_have_function_literal(bool value) { | 
| may_have_function_literal_ = value; | 
| } | 
| - virtual bool IsInlineable() const; | 
| // Bailout support. | 
| virtual int ContinueId() const { return EntryId(); } | 
| virtual int StackCheckId() const { return body_id_; } | 
| int BodyId() const { return body_id_; } | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| + WhileStatement(Isolate* isolate, ZoneStringList* labels) | 
| + : IterationStatement(isolate, labels), | 
| + cond_(NULL), | 
| + may_have_function_literal_(true), | 
| + body_id_(GetNextId(isolate)) { | 
| + } | 
| + | 
| private: | 
| Expression* cond_; | 
| // True if there is a function literal subexpression in the condition. | 
| @@ -554,17 +594,6 @@ class WhileStatement: public IterationStatement { | 
| class ForStatement: public IterationStatement { | 
| public: | 
| - ForStatement(Isolate* isolate, ZoneStringList* labels) | 
| - : IterationStatement(isolate, labels), | 
| - init_(NULL), | 
| - cond_(NULL), | 
| - next_(NULL), | 
| - may_have_function_literal_(true), | 
| - loop_variable_(NULL), | 
| - continue_id_(GetNextId(isolate)), | 
| - body_id_(GetNextId(isolate)) { | 
| - } | 
| - | 
| DECLARE_NODE_TYPE(ForStatement) | 
| void Initialize(Statement* init, | 
| @@ -596,7 +625,20 @@ class ForStatement: public IterationStatement { | 
| bool is_fast_smi_loop() { return loop_variable_ != NULL; } | 
| Variable* loop_variable() { return loop_variable_; } | 
| void set_loop_variable(Variable* var) { loop_variable_ = var; } | 
| - virtual bool IsInlineable() const; | 
| + | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| + ForStatement(Isolate* isolate, ZoneStringList* labels) | 
| + : IterationStatement(isolate, labels), | 
| + init_(NULL), | 
| + cond_(NULL), | 
| + next_(NULL), | 
| + may_have_function_literal_(true), | 
| + loop_variable_(NULL), | 
| + continue_id_(GetNextId(isolate)), | 
| + body_id_(GetNextId(isolate)) { | 
| + } | 
| private: | 
| Statement* init_; | 
| @@ -612,13 +654,6 @@ class ForStatement: public IterationStatement { | 
| class ForInStatement: public IterationStatement { | 
| public: | 
| - ForInStatement(Isolate* isolate, ZoneStringList* labels) | 
| - : IterationStatement(isolate, labels), | 
| - each_(NULL), | 
| - enumerable_(NULL), | 
| - assignment_id_(GetNextId(isolate)) { | 
| - } | 
| - | 
| DECLARE_NODE_TYPE(ForInStatement) | 
| void Initialize(Expression* each, Expression* enumerable, Statement* body) { | 
| @@ -629,13 +664,22 @@ class ForInStatement: public IterationStatement { | 
| Expression* each() const { return each_; } | 
| Expression* enumerable() const { return enumerable_; } | 
| - virtual bool IsInlineable() const; | 
| // Bailout support. | 
| int AssignmentId() const { return assignment_id_; } | 
| virtual int ContinueId() const { return EntryId(); } | 
| virtual int StackCheckId() const { return EntryId(); } | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| + ForInStatement(Isolate* isolate, ZoneStringList* labels) | 
| + : IterationStatement(isolate, labels), | 
| + each_(NULL), | 
| + enumerable_(NULL), | 
| + assignment_id_(GetNextId(isolate)) { | 
| + } | 
| + | 
| private: | 
| Expression* each_; | 
| Expression* enumerable_; | 
| @@ -645,16 +689,17 @@ class ForInStatement: public IterationStatement { | 
| class ExpressionStatement: public Statement { | 
| public: | 
| - explicit ExpressionStatement(Expression* expression) | 
| - : expression_(expression) { } | 
| - | 
| DECLARE_NODE_TYPE(ExpressionStatement) | 
| - virtual bool IsInlineable() const; | 
| - | 
| void set_expression(Expression* e) { expression_ = e; } | 
| Expression* expression() const { return expression_; } | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| + explicit ExpressionStatement(Expression* expression) | 
| + : expression_(expression) { } | 
| + | 
| private: | 
| Expression* expression_; | 
| }; | 
| @@ -662,13 +707,15 @@ class ExpressionStatement: public Statement { | 
| class ContinueStatement: public Statement { | 
| public: | 
| - explicit ContinueStatement(IterationStatement* target) | 
| - : target_(target) { } | 
| - | 
| DECLARE_NODE_TYPE(ContinueStatement) | 
| IterationStatement* target() const { return target_; } | 
| - virtual bool IsInlineable() const; | 
| + | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| + explicit ContinueStatement(IterationStatement* target) | 
| + : target_(target) { } | 
| private: | 
| IterationStatement* target_; | 
| @@ -677,13 +724,15 @@ class ContinueStatement: public Statement { | 
| class BreakStatement: public Statement { | 
| public: | 
| - explicit BreakStatement(BreakableStatement* target) | 
| - : target_(target) { } | 
| - | 
| DECLARE_NODE_TYPE(BreakStatement) | 
| BreakableStatement* target() const { return target_; } | 
| - virtual bool IsInlineable() const; | 
| + | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| + explicit BreakStatement(BreakableStatement* target) | 
| + : target_(target) { } | 
| private: | 
| BreakableStatement* target_; | 
| @@ -692,13 +741,15 @@ class BreakStatement: public Statement { | 
| class ReturnStatement: public Statement { | 
| public: | 
| - explicit ReturnStatement(Expression* expression) | 
| - : expression_(expression) { } | 
| - | 
| DECLARE_NODE_TYPE(ReturnStatement) | 
| Expression* expression() const { return expression_; } | 
| - virtual bool IsInlineable() const; | 
| + | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| + explicit ReturnStatement(Expression* expression) | 
| + : expression_(expression) { } | 
| private: | 
| Expression* expression_; | 
| @@ -707,15 +758,17 @@ class ReturnStatement: public Statement { | 
| class WithStatement: public Statement { | 
| public: | 
| - WithStatement(Expression* expression, Statement* statement) | 
| - : expression_(expression), statement_(statement) { } | 
| - | 
| DECLARE_NODE_TYPE(WithStatement) | 
| Expression* expression() const { return expression_; } | 
| Statement* statement() const { return statement_; } | 
| - virtual bool IsInlineable() const; | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| + WithStatement(Expression* expression, Statement* statement) | 
| + : expression_(expression), | 
| + statement_(statement) { } | 
| private: | 
| Expression* expression_; | 
| @@ -771,13 +824,6 @@ class CaseClause: public ZoneObject { | 
| class SwitchStatement: public BreakableStatement { | 
| public: | 
| - SwitchStatement(Isolate* isolate, ZoneStringList* labels) | 
| - : BreakableStatement(isolate, labels, TARGET_FOR_ANONYMOUS), | 
| - tag_(NULL), | 
| - cases_(NULL) { | 
| - } | 
| - | 
| - | 
| DECLARE_NODE_TYPE(SwitchStatement) | 
| void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) { | 
| @@ -787,7 +833,14 @@ class SwitchStatement: public BreakableStatement { | 
| Expression* tag() const { return tag_; } | 
| ZoneList<CaseClause*>* cases() const { return cases_; } | 
| - virtual bool IsInlineable() const; | 
| + | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| + SwitchStatement(Isolate* isolate, ZoneStringList* labels) | 
| + : BreakableStatement(isolate, labels, TARGET_FOR_ANONYMOUS), | 
| + tag_(NULL), | 
| + cases_(NULL) { } | 
| private: | 
| Expression* tag_; | 
| @@ -802,22 +855,8 @@ class SwitchStatement: public BreakableStatement { | 
| // given if-statement has a then- or an else-part containing code. | 
| class IfStatement: public Statement { | 
| public: | 
| - IfStatement(Isolate* isolate, | 
| - Expression* condition, | 
| - Statement* then_statement, | 
| - Statement* else_statement) | 
| - : condition_(condition), | 
| - then_statement_(then_statement), | 
| - else_statement_(else_statement), | 
| - if_id_(GetNextId(isolate)), | 
| - then_id_(GetNextId(isolate)), | 
| - else_id_(GetNextId(isolate)) { | 
| - } | 
| - | 
| DECLARE_NODE_TYPE(IfStatement) | 
| - virtual bool IsInlineable() const; | 
| - | 
| bool HasThenStatement() const { return !then_statement()->IsEmpty(); } | 
| bool HasElseStatement() const { return !else_statement()->IsEmpty(); } | 
| @@ -829,6 +868,21 @@ class IfStatement: public Statement { | 
| int ThenId() const { return then_id_; } | 
| int ElseId() const { return else_id_; } | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| + IfStatement(Isolate* isolate, | 
| + Expression* condition, | 
| + Statement* then_statement, | 
| + Statement* else_statement) | 
| + : condition_(condition), | 
| + then_statement_(then_statement), | 
| + else_statement_(else_statement), | 
| + if_id_(GetNextId(isolate)), | 
| + then_id_(GetNextId(isolate)), | 
| + else_id_(GetNextId(isolate)) { | 
| + } | 
| + | 
| private: | 
| Expression* condition_; | 
| Statement* then_statement_; | 
| @@ -843,7 +897,7 @@ class IfStatement: public Statement { | 
| // stack in the compiler; this should probably be reworked. | 
| class TargetCollector: public AstNode { | 
| public: | 
| - TargetCollector(): targets_(0) { } | 
| + TargetCollector() : targets_(0) { } | 
| // Adds a jump target to the collector. The collector stores a pointer not | 
| // a copy of the target to make binding work, so make sure not to pass in | 
| @@ -855,7 +909,6 @@ class TargetCollector: public AstNode { | 
| virtual TargetCollector* AsTargetCollector() { return this; } | 
| ZoneList<Label*>* targets() { return &targets_; } | 
| - virtual bool IsInlineable() const; | 
| private: | 
| ZoneList<Label*> targets_; | 
| @@ -864,12 +917,6 @@ class TargetCollector: public AstNode { | 
| class TryStatement: public Statement { | 
| public: | 
| - explicit TryStatement(int index, Block* try_block) | 
| - : index_(index), | 
| - try_block_(try_block), | 
| - escaping_targets_(NULL) { | 
| - } | 
| - | 
| void set_escaping_targets(ZoneList<Label*>* targets) { | 
| escaping_targets_ = targets; | 
| } | 
| @@ -877,7 +924,12 @@ class TryStatement: public Statement { | 
| int index() const { return index_; } | 
| Block* try_block() const { return try_block_; } | 
| ZoneList<Label*>* escaping_targets() const { return escaping_targets_; } | 
| - virtual bool IsInlineable() const; | 
| + | 
| + protected: | 
| + TryStatement(int index, Block* try_block) | 
| + : index_(index), | 
| + try_block_(try_block), | 
| + escaping_targets_(NULL) { } | 
| private: | 
| // Unique (per-function) index of this handler. This is not an AST ID. | 
| @@ -890,6 +942,15 @@ class TryStatement: public Statement { | 
| class TryCatchStatement: public TryStatement { | 
| public: | 
| + DECLARE_NODE_TYPE(TryCatchStatement) | 
| + | 
| + Scope* scope() { return scope_; } | 
| + Variable* variable() { return variable_; } | 
| + Block* catch_block() const { return catch_block_; } | 
| + | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| TryCatchStatement(int index, | 
| Block* try_block, | 
| Scope* scope, | 
| @@ -901,13 +962,6 @@ class TryCatchStatement: public TryStatement { | 
| catch_block_(catch_block) { | 
| } | 
| - DECLARE_NODE_TYPE(TryCatchStatement) | 
| - | 
| - Scope* scope() { return scope_; } | 
| - Variable* variable() { return variable_; } | 
| - Block* catch_block() const { return catch_block_; } | 
| - virtual bool IsInlineable() const; | 
| - | 
| private: | 
| Scope* scope_; | 
| Variable* variable_; | 
| @@ -917,14 +971,16 @@ class TryCatchStatement: public TryStatement { | 
| class TryFinallyStatement: public TryStatement { | 
| public: | 
| - TryFinallyStatement(int index, Block* try_block, Block* finally_block) | 
| - : TryStatement(index, try_block), | 
| - finally_block_(finally_block) { } | 
| - | 
| DECLARE_NODE_TYPE(TryFinallyStatement) | 
| Block* finally_block() const { return finally_block_; } | 
| - virtual bool IsInlineable() const; | 
| + | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| + TryFinallyStatement(int index, Block* try_block, Block* finally_block) | 
| + : TryStatement(index, try_block), | 
| + finally_block_(finally_block) { } | 
| private: | 
| Block* finally_block_; | 
| @@ -934,7 +990,11 @@ class TryFinallyStatement: public TryStatement { | 
| class DebuggerStatement: public Statement { | 
| public: | 
| DECLARE_NODE_TYPE(DebuggerStatement) | 
| - virtual bool IsInlineable() const; | 
| + | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| + DebuggerStatement() {} | 
| }; | 
| @@ -942,15 +1002,15 @@ class EmptyStatement: public Statement { | 
| public: | 
| DECLARE_NODE_TYPE(EmptyStatement) | 
| - virtual bool IsInlineable() const; | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| + EmptyStatement() {} | 
| }; | 
| class Literal: public Expression { | 
| public: | 
| - Literal(Isolate* isolate, Handle<Object> handle) | 
| - : Expression(isolate), handle_(handle) { } | 
| - | 
| DECLARE_NODE_TYPE(Literal) | 
| // Check if this literal is identical to the other literal. | 
| @@ -989,7 +1049,13 @@ class Literal: public Expression { | 
| } | 
| Handle<Object> handle() const { return handle_; } | 
| - virtual bool IsInlineable() const; | 
| + | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| + Literal(Isolate* isolate, Handle<Object> handle) | 
| + : Expression(isolate), | 
| + handle_(handle) { } | 
| private: | 
| Handle<Object> handle_; | 
| @@ -999,15 +1065,6 @@ class Literal: public Expression { | 
| // Base class for literals that needs space in the corresponding JSFunction. | 
| class MaterializedLiteral: public Expression { | 
| public: | 
| - MaterializedLiteral(Isolate* isolate, | 
| - int literal_index, | 
| - bool is_simple, | 
| - int depth) | 
| - : Expression(isolate), | 
| - literal_index_(literal_index), | 
| - is_simple_(is_simple), | 
| - depth_(depth) {} | 
| - | 
| virtual MaterializedLiteral* AsMaterializedLiteral() { return this; } | 
| int literal_index() { return literal_index_; } | 
| @@ -1017,7 +1074,16 @@ class MaterializedLiteral: public Expression { | 
| bool is_simple() const { return is_simple_; } | 
| int depth() const { return depth_; } | 
| - virtual bool IsInlineable() const; | 
| + | 
| + protected: | 
| + MaterializedLiteral(Isolate* isolate, | 
| + int literal_index, | 
| + bool is_simple, | 
| + int depth) | 
| + : Expression(isolate), | 
| + literal_index_(literal_index), | 
| + is_simple_(is_simple), | 
| + depth_(depth) {} | 
| private: | 
| int literal_index_; | 
| @@ -1044,7 +1110,6 @@ class ObjectLiteral: public MaterializedLiteral { | 
| }; | 
| Property(Literal* key, Expression* value); | 
| - Property(bool is_getter, FunctionLiteral* value); | 
| Literal* key() { return key_; } | 
| Expression* value() { return value_; } | 
| @@ -1055,6 +1120,12 @@ class ObjectLiteral: public MaterializedLiteral { | 
| void set_emit_store(bool emit_store); | 
| bool emit_store(); | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| + Property(bool is_getter, FunctionLiteral* value); | 
| + void set_key(Literal* key) { key_ = key; } | 
| + | 
| private: | 
| Literal* key_; | 
| Expression* value_; | 
| @@ -1062,20 +1133,6 @@ class ObjectLiteral: public MaterializedLiteral { | 
| bool emit_store_; | 
| }; | 
| - ObjectLiteral(Isolate* isolate, | 
| - Handle<FixedArray> constant_properties, | 
| - ZoneList<Property*>* properties, | 
| - int literal_index, | 
| - bool is_simple, | 
| - bool fast_elements, | 
| - int depth, | 
| - bool has_function) | 
| - : MaterializedLiteral(isolate, literal_index, is_simple, depth), | 
| - constant_properties_(constant_properties), | 
| - properties_(properties), | 
| - fast_elements_(fast_elements), | 
| - has_function_(has_function) {} | 
| - | 
| DECLARE_NODE_TYPE(ObjectLiteral) | 
| Handle<FixedArray> constant_properties() const { | 
| @@ -1098,6 +1155,23 @@ class ObjectLiteral: public MaterializedLiteral { | 
| kHasFunction = 1 << 1 | 
| }; | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| + ObjectLiteral(Isolate* isolate, | 
| + Handle<FixedArray> constant_properties, | 
| + ZoneList<Property*>* properties, | 
| + int literal_index, | 
| + bool is_simple, | 
| + bool fast_elements, | 
| + int depth, | 
| + bool has_function) | 
| + : MaterializedLiteral(isolate, literal_index, is_simple, depth), | 
| + constant_properties_(constant_properties), | 
| + properties_(properties), | 
| + fast_elements_(fast_elements), | 
| + has_function_(has_function) {} | 
| + | 
| private: | 
| Handle<FixedArray> constant_properties_; | 
| ZoneList<Property*>* properties_; | 
| @@ -1109,6 +1183,14 @@ class ObjectLiteral: public MaterializedLiteral { | 
| // Node for capturing a regexp literal. | 
| class RegExpLiteral: public MaterializedLiteral { | 
| public: | 
| + DECLARE_NODE_TYPE(RegExpLiteral) | 
| + | 
| + Handle<String> pattern() const { return pattern_; } | 
| + Handle<String> flags() const { return flags_; } | 
| + | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| RegExpLiteral(Isolate* isolate, | 
| Handle<String> pattern, | 
| Handle<String> flags, | 
| @@ -1117,11 +1199,6 @@ class RegExpLiteral: public MaterializedLiteral { | 
| pattern_(pattern), | 
| flags_(flags) {} | 
| - DECLARE_NODE_TYPE(RegExpLiteral) | 
| - | 
| - Handle<String> pattern() const { return pattern_; } | 
| - Handle<String> flags() const { return flags_; } | 
| - | 
| private: | 
| Handle<String> pattern_; | 
| Handle<String> flags_; | 
| @@ -1131,6 +1208,17 @@ class RegExpLiteral: public MaterializedLiteral { | 
| // for minimizing the work when constructing it at runtime. | 
| class ArrayLiteral: public MaterializedLiteral { | 
| public: | 
| + DECLARE_NODE_TYPE(ArrayLiteral) | 
| + | 
| + Handle<FixedArray> constant_elements() const { return constant_elements_; } | 
| + ZoneList<Expression*>* values() const { return values_; } | 
| + | 
| + // Return an AST id for an element that is used in simulate instructions. | 
| + int GetIdForElement(int i) { return first_element_id_ + i; } | 
| + | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| ArrayLiteral(Isolate* isolate, | 
| Handle<FixedArray> constant_elements, | 
| ZoneList<Expression*>* values, | 
| @@ -1142,14 +1230,6 @@ class ArrayLiteral: public MaterializedLiteral { | 
| values_(values), | 
| first_element_id_(ReserveIdRange(isolate, values->length())) {} | 
| - DECLARE_NODE_TYPE(ArrayLiteral) | 
| - | 
| - Handle<FixedArray> constant_elements() const { return constant_elements_; } | 
| - ZoneList<Expression*>* values() const { return values_; } | 
| - | 
| - // Return an AST id for an element that is used in simulate instructions. | 
| - int GetIdForElement(int i) { return first_element_id_ + i; } | 
| - | 
| private: | 
| Handle<FixedArray> constant_elements_; | 
| ZoneList<Expression*>* values_; | 
| @@ -1159,21 +1239,12 @@ class ArrayLiteral: public MaterializedLiteral { | 
| class VariableProxy: public Expression { | 
| public: | 
| - VariableProxy(Isolate* isolate, Variable* var); | 
| - | 
| - VariableProxy(Isolate* isolate, | 
| - Handle<String> name, | 
| - bool is_this, | 
| - int position = RelocInfo::kNoPosition); | 
| - | 
| DECLARE_NODE_TYPE(VariableProxy) | 
| virtual bool IsValidLeftHandSide() { | 
| return var_ == NULL ? true : var_->IsValidLeftHandSide(); | 
| } | 
| - virtual bool IsInlineable() const; | 
| - | 
| bool IsVariable(Handle<String> n) { | 
| return !is_this() && name().is_identical_to(n); | 
| } | 
| @@ -1196,6 +1267,15 @@ class VariableProxy: public Expression { | 
| void BindTo(Variable* var); | 
| protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| + VariableProxy(Isolate* isolate, Variable* var); | 
| + | 
| + VariableProxy(Isolate* isolate, | 
| + Handle<String> name, | 
| + bool is_this, | 
| + int position); | 
| + | 
| Handle<String> name_; | 
| Variable* var_; // resolved variable, or NULL | 
| bool is_this_; | 
| @@ -1209,24 +1289,9 @@ class VariableProxy: public Expression { | 
| class Property: public Expression { | 
| public: | 
| - Property(Isolate* isolate, | 
| - Expression* obj, | 
| - Expression* key, | 
| - int pos) | 
| - : Expression(isolate), | 
| - obj_(obj), | 
| - key_(key), | 
| - pos_(pos), | 
| - is_monomorphic_(false), | 
| - is_array_length_(false), | 
| - is_string_length_(false), | 
| - is_string_access_(false), | 
| - is_function_prototype_(false) { } | 
| - | 
| DECLARE_NODE_TYPE(Property) | 
| virtual bool IsValidLeftHandSide() { return true; } | 
| - virtual bool IsInlineable() const; | 
| Expression* obj() const { return obj_; } | 
| Expression* key() const { return key_; } | 
| @@ -1242,6 +1307,23 @@ class Property: public Expression { | 
| virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; } | 
| bool IsArrayLength() { return is_array_length_; } | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| + Property(Isolate* isolate, | 
| + Expression* obj, | 
| + Expression* key, | 
| + int pos) | 
| + : Expression(isolate), | 
| + obj_(obj), | 
| + key_(key), | 
| + pos_(pos), | 
| + is_monomorphic_(false), | 
| + is_array_length_(false), | 
| + is_string_length_(false), | 
| + is_string_access_(false), | 
| + is_function_prototype_(false) { } | 
| + | 
| private: | 
| Expression* obj_; | 
| Expression* key_; | 
| @@ -1258,23 +1340,8 @@ class Property: public Expression { | 
| class Call: public Expression { | 
| public: | 
| - Call(Isolate* isolate, | 
| - Expression* expression, | 
| - ZoneList<Expression*>* arguments, | 
| - int pos) | 
| - : Expression(isolate), | 
| - expression_(expression), | 
| - arguments_(arguments), | 
| - pos_(pos), | 
| - is_monomorphic_(false), | 
| - check_type_(RECEIVER_MAP_CHECK), | 
| - return_id_(GetNextId(isolate)) { | 
| - } | 
| - | 
| DECLARE_NODE_TYPE(Call) | 
| - virtual bool IsInlineable() const; | 
| - | 
| Expression* expression() const { return expression_; } | 
| ZoneList<Expression*>* arguments() const { return arguments_; } | 
| virtual int position() const { return pos_; } | 
| @@ -1299,6 +1366,21 @@ class Call: public Expression { | 
| bool return_is_recorded_; | 
| #endif | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| + Call(Isolate* isolate, | 
| + Expression* expression, | 
| + ZoneList<Expression*>* arguments, | 
| + int pos) | 
| + : Expression(isolate), | 
| + expression_(expression), | 
| + arguments_(arguments), | 
| + pos_(pos), | 
| + is_monomorphic_(false), | 
| + check_type_(RECEIVER_MAP_CHECK), | 
| + return_id_(GetNextId(isolate)) { } | 
| + | 
| private: | 
| Expression* expression_; | 
| ZoneList<Expression*>* arguments_; | 
| @@ -1317,6 +1399,15 @@ class Call: public Expression { | 
| class CallNew: public Expression { | 
| public: | 
| + DECLARE_NODE_TYPE(CallNew) | 
| + | 
| + Expression* expression() const { return expression_; } | 
| + ZoneList<Expression*>* arguments() const { return arguments_; } | 
| + virtual int position() const { return pos_; } | 
| + | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| CallNew(Isolate* isolate, | 
| Expression* expression, | 
| ZoneList<Expression*>* arguments, | 
| @@ -1326,14 +1417,6 @@ class CallNew: public Expression { | 
| arguments_(arguments), | 
| pos_(pos) { } | 
| - DECLARE_NODE_TYPE(CallNew) | 
| - | 
| - virtual bool IsInlineable() const; | 
| - | 
| - Expression* expression() const { return expression_; } | 
| - ZoneList<Expression*>* arguments() const { return arguments_; } | 
| - virtual int position() const { return pos_; } | 
| - | 
| private: | 
| Expression* expression_; | 
| ZoneList<Expression*>* arguments_; | 
| @@ -1347,6 +1430,16 @@ class CallNew: public Expression { | 
| // implemented in JavaScript (see "v8natives.js"). | 
| class CallRuntime: public Expression { | 
| public: | 
| + DECLARE_NODE_TYPE(CallRuntime) | 
| + | 
| + Handle<String> name() const { return name_; } | 
| + const Runtime::Function* function() const { return function_; } | 
| + ZoneList<Expression*>* arguments() const { return arguments_; } | 
| + bool is_jsruntime() const { return function_ == NULL; } | 
| + | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| CallRuntime(Isolate* isolate, | 
| Handle<String> name, | 
| const Runtime::Function* function, | 
| @@ -1356,15 +1449,6 @@ class CallRuntime: public Expression { | 
| function_(function), | 
| arguments_(arguments) { } | 
| - DECLARE_NODE_TYPE(CallRuntime) | 
| - | 
| - virtual bool IsInlineable() const; | 
| - | 
| - Handle<String> name() const { return name_; } | 
| - const Runtime::Function* function() const { return function_; } | 
| - ZoneList<Expression*>* arguments() const { return arguments_; } | 
| - bool is_jsruntime() const { return function_ == NULL; } | 
| - | 
| private: | 
| Handle<String> name_; | 
| const Runtime::Function* function_; | 
| @@ -1374,6 +1458,20 @@ class CallRuntime: public Expression { | 
| class UnaryOperation: public Expression { | 
| public: | 
| + DECLARE_NODE_TYPE(UnaryOperation) | 
| + | 
| + virtual bool ResultOverwriteAllowed(); | 
| + | 
| + Token::Value op() const { return op_; } | 
| + Expression* expression() const { return expression_; } | 
| + virtual int position() const { return pos_; } | 
| + | 
| + int MaterializeTrueId() { return materialize_true_id_; } | 
| + int MaterializeFalseId() { return materialize_false_id_; } | 
| + | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| UnaryOperation(Isolate* isolate, | 
| Token::Value op, | 
| Expression* expression, | 
| @@ -1391,19 +1489,6 @@ class UnaryOperation: public Expression { | 
| } | 
| } | 
| - DECLARE_NODE_TYPE(UnaryOperation) | 
| - | 
| - virtual bool IsInlineable() const; | 
| - | 
| - virtual bool ResultOverwriteAllowed(); | 
| - | 
| - Token::Value op() const { return op_; } | 
| - Expression* expression() const { return expression_; } | 
| - virtual int position() const { return pos_; } | 
| - | 
| - int MaterializeTrueId() { return materialize_true_id_; } | 
| - int MaterializeFalseId() { return materialize_false_id_; } | 
| - | 
| private: | 
| Token::Value op_; | 
| Expression* expression_; | 
| @@ -1418,22 +1503,8 @@ class UnaryOperation: public Expression { | 
| class BinaryOperation: public Expression { | 
| public: | 
| - BinaryOperation(Isolate* isolate, | 
| - Token::Value op, | 
| - Expression* left, | 
| - Expression* right, | 
| - int pos) | 
| - : Expression(isolate), op_(op), left_(left), right_(right), pos_(pos) { | 
| - ASSERT(Token::IsBinaryOp(op)); | 
| - right_id_ = (op == Token::AND || op == Token::OR) | 
| - ? static_cast<int>(GetNextId(isolate)) | 
| - : AstNode::kNoNumber; | 
| - } | 
| - | 
| DECLARE_NODE_TYPE(BinaryOperation) | 
| - virtual bool IsInlineable() const; | 
| - | 
| virtual bool ResultOverwriteAllowed(); | 
| Token::Value op() const { return op_; } | 
| @@ -1444,6 +1515,21 @@ class BinaryOperation: public Expression { | 
| // Bailout support. | 
| int RightId() const { return right_id_; } | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| + BinaryOperation(Isolate* isolate, | 
| + Token::Value op, | 
| + Expression* left, | 
| + Expression* right, | 
| + int pos) | 
| + : Expression(isolate), op_(op), left_(left), right_(right), pos_(pos) { | 
| + ASSERT(Token::IsBinaryOp(op)); | 
| + right_id_ = (op == Token::AND || op == Token::OR) | 
| + ? GetNextId(isolate) | 
| + : AstNode::kNoNumber; | 
| + } | 
| + | 
| private: | 
| Token::Value op_; | 
| Expression* left_; | 
| @@ -1457,19 +1543,6 @@ class BinaryOperation: public Expression { | 
| class CountOperation: public Expression { | 
| public: | 
| - CountOperation(Isolate* isolate, | 
| - Token::Value op, | 
| - bool is_prefix, | 
| - Expression* expr, | 
| - int pos) | 
| - : Expression(isolate), | 
| - op_(op), | 
| - is_prefix_(is_prefix), | 
| - expression_(expr), | 
| - pos_(pos), | 
| - assignment_id_(GetNextId(isolate)), | 
| - count_id_(GetNextId(isolate)) {} | 
| - | 
| DECLARE_NODE_TYPE(CountOperation) | 
| bool is_prefix() const { return is_prefix_; } | 
| @@ -1485,8 +1558,6 @@ class CountOperation: public Expression { | 
| virtual void MarkAsStatement() { is_prefix_ = true; } | 
| - virtual bool IsInlineable() const; | 
| - | 
| void RecordTypeFeedback(TypeFeedbackOracle* oracle); | 
| virtual bool IsMonomorphic() { return is_monomorphic_; } | 
| virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; } | 
| @@ -1495,6 +1566,22 @@ class CountOperation: public Expression { | 
| int AssignmentId() const { return assignment_id_; } | 
| int CountId() const { return count_id_; } | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| + CountOperation(Isolate* isolate, | 
| + Token::Value op, | 
| + bool is_prefix, | 
| + Expression* expr, | 
| + int pos) | 
| + : Expression(isolate), | 
| + op_(op), | 
| + is_prefix_(is_prefix), | 
| + expression_(expr), | 
| + pos_(pos), | 
| + assignment_id_(GetNextId(isolate)), | 
| + count_id_(GetNextId(isolate)) {} | 
| + | 
| private: | 
| Token::Value op_; | 
| bool is_prefix_; | 
| @@ -1508,21 +1595,7 @@ class CountOperation: public Expression { | 
| class CompareOperation: public Expression { | 
| - public: | 
| - CompareOperation(Isolate* isolate, | 
| - Token::Value op, | 
| - Expression* left, | 
| - Expression* right, | 
| - int pos) | 
| - : Expression(isolate), | 
| - op_(op), | 
| - left_(left), | 
| - right_(right), | 
| - pos_(pos), | 
| - compare_type_(NONE) { | 
| - ASSERT(Token::IsCompareOp(op)); | 
| - } | 
| - | 
| + public: | 
| DECLARE_NODE_TYPE(CompareOperation) | 
| Token::Value op() const { return op_; } | 
| @@ -1530,8 +1603,6 @@ class CompareOperation: public Expression { | 
| Expression* right() const { return right_; } | 
| virtual int position() const { return pos_; } | 
| - virtual bool IsInlineable() const; | 
| - | 
| // Type feedback information. | 
| void RecordTypeFeedback(TypeFeedbackOracle* oracle); | 
| bool IsSmiCompare() { return compare_type_ == SMI_ONLY; } | 
| @@ -1542,6 +1613,23 @@ class CompareOperation: public Expression { | 
| bool IsLiteralCompareUndefined(Expression** expr); | 
| bool IsLiteralCompareNull(Expression** expr); | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| + CompareOperation(Isolate* isolate, | 
| + Token::Value op, | 
| + Expression* left, | 
| + Expression* right, | 
| + int pos) | 
| + : Expression(isolate), | 
| + op_(op), | 
| + left_(left), | 
| + right_(right), | 
| + pos_(pos), | 
| + compare_type_(NONE) { | 
| + ASSERT(Token::IsCompareOp(op)); | 
| + } | 
| + | 
| private: | 
| Token::Value op_; | 
| Expression* left_; | 
| @@ -1555,6 +1643,21 @@ class CompareOperation: public Expression { | 
| class Conditional: public Expression { | 
| public: | 
| + DECLARE_NODE_TYPE(Conditional) | 
| + | 
| + Expression* condition() const { return condition_; } | 
| + Expression* then_expression() const { return then_expression_; } | 
| + Expression* else_expression() const { return else_expression_; } | 
| + | 
| + int then_expression_position() const { return then_expression_position_; } | 
| + int else_expression_position() const { return else_expression_position_; } | 
| + | 
| + int ThenId() const { return then_id_; } | 
| + int ElseId() const { return else_id_; } | 
| + | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| Conditional(Isolate* isolate, | 
| Expression* condition, | 
| Expression* then_expression, | 
| @@ -1568,22 +1671,7 @@ class Conditional: public Expression { | 
| then_expression_position_(then_expression_position), | 
| else_expression_position_(else_expression_position), | 
| then_id_(GetNextId(isolate)), | 
| - else_id_(GetNextId(isolate)) { | 
| - } | 
| - | 
| - DECLARE_NODE_TYPE(Conditional) | 
| - | 
| - virtual bool IsInlineable() const; | 
| - | 
| - Expression* condition() const { return condition_; } | 
| - Expression* then_expression() const { return then_expression_; } | 
| - Expression* else_expression() const { return else_expression_; } | 
| - | 
| - int then_expression_position() const { return then_expression_position_; } | 
| - int else_expression_position() const { return else_expression_position_; } | 
| - | 
| - int ThenId() const { return then_id_; } | 
| - int ElseId() const { return else_id_; } | 
| + else_id_(GetNextId(isolate)) { } | 
| private: | 
| Expression* condition_; | 
| @@ -1598,16 +1686,8 @@ class Conditional: public Expression { | 
| class Assignment: public Expression { | 
| public: | 
| - Assignment(Isolate* isolate, | 
| - Token::Value op, | 
| - Expression* target, | 
| - Expression* value, | 
| - int pos); | 
| - | 
| DECLARE_NODE_TYPE(Assignment) | 
| - virtual bool IsInlineable() const; | 
| - | 
| Assignment* AsSimpleAssignment() { return !is_compound() ? this : NULL; } | 
| Token::Value binary_op() const; | 
| @@ -1639,6 +1719,25 @@ class Assignment: public Expression { | 
| int CompoundLoadId() const { return compound_load_id_; } | 
| int AssignmentId() const { return assignment_id_; } | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| + Assignment(Isolate* isolate, | 
| + Token::Value op, | 
| + Expression* target, | 
| + Expression* value, | 
| + int pos); | 
| + | 
| + template<class Visitor> | 
| + void Init(Isolate* isolate, AstNodeFactory<Visitor>* factory) { | 
| + ASSERT(Token::IsAssignmentOp(op_)); | 
| + if (is_compound()) { | 
| + binary_operation_ = | 
| + factory->NewBinaryOperation(binary_op(), target_, value_, pos_ + 1); | 
| + compound_load_id_ = GetNextId(isolate); | 
| + } | 
| + } | 
| + | 
| private: | 
| Token::Value op_; | 
| Expression* target_; | 
| @@ -1658,14 +1757,16 @@ class Assignment: public Expression { | 
| class Throw: public Expression { | 
| public: | 
| - Throw(Isolate* isolate, Expression* exception, int pos) | 
| - : Expression(isolate), exception_(exception), pos_(pos) {} | 
| - | 
| DECLARE_NODE_TYPE(Throw) | 
| Expression* exception() const { return exception_; } | 
| virtual int position() const { return pos_; } | 
| - virtual bool IsInlineable() const; | 
| + | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| + Throw(Isolate* isolate, Expression* exception, int pos) | 
| + : Expression(isolate), exception_(exception), pos_(pos) {} | 
| private: | 
| Expression* exception_; | 
| @@ -1681,38 +1782,6 @@ class FunctionLiteral: public Expression { | 
| DECLARATION | 
| }; | 
| - 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, | 
| - bool has_duplicate_parameters) | 
| - : Expression(isolate), | 
| - name_(name), | 
| - scope_(scope), | 
| - body_(body), | 
| - this_property_assignments_(this_property_assignments), | 
| - inferred_name_(isolate->factory()->empty_string()), | 
| - materialized_literal_count_(materialized_literal_count), | 
| - expected_property_count_(expected_property_count), | 
| - handler_count_(handler_count), | 
| - parameter_count_(parameter_count), | 
| - function_token_position_(RelocInfo::kNoPosition) { | 
| - bitfield_ = | 
| - HasOnlySimpleThisPropertyAssignments::encode( | 
| - has_only_simple_this_property_assignments) | | 
| - IsExpression::encode(type != DECLARATION) | | 
| - IsAnonymous::encode(type == ANONYMOUS_EXPRESSION) | | 
| - Pretenure::encode(false) | | 
| - HasDuplicateParameters::encode(has_duplicate_parameters); | 
| - } | 
| - | 
| DECLARE_NODE_TYPE(FunctionLiteral) | 
| Handle<String> name() const { return name_; } | 
| @@ -1752,18 +1821,61 @@ class FunctionLiteral: public Expression { | 
| bool pretenure() { return Pretenure::decode(bitfield_); } | 
| void set_pretenure() { bitfield_ |= Pretenure::encode(true); } | 
| - virtual bool IsInlineable() const; | 
| bool has_duplicate_parameters() { | 
| return HasDuplicateParameters::decode(bitfield_); | 
| } | 
| + bool ShouldSelfOptimize(); | 
| + | 
| + int ast_node_count() { return ast_properties_.node_count(); } | 
| + AstProperties::Flags* flags() { return ast_properties_.flags(); } | 
| + void set_ast_properties(AstProperties* ast_properties) { | 
| + ast_properties_ = *ast_properties; | 
| + } | 
| + | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| + 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, | 
| + bool has_duplicate_parameters) | 
| + : Expression(isolate), | 
| + name_(name), | 
| + scope_(scope), | 
| + body_(body), | 
| + this_property_assignments_(this_property_assignments), | 
| + inferred_name_(isolate->factory()->empty_string()), | 
| + materialized_literal_count_(materialized_literal_count), | 
| + expected_property_count_(expected_property_count), | 
| + handler_count_(handler_count), | 
| + parameter_count_(parameter_count), | 
| + function_token_position_(RelocInfo::kNoPosition) { | 
| + bitfield_ = | 
| + HasOnlySimpleThisPropertyAssignments::encode( | 
| + has_only_simple_this_property_assignments) | | 
| + IsExpression::encode(type != DECLARATION) | | 
| + IsAnonymous::encode(type == ANONYMOUS_EXPRESSION) | | 
| + Pretenure::encode(false) | | 
| + HasDuplicateParameters::encode(has_duplicate_parameters); | 
| + } | 
| + | 
| private: | 
| Handle<String> name_; | 
| Scope* scope_; | 
| ZoneList<Statement*>* body_; | 
| Handle<FixedArray> this_property_assignments_; | 
| Handle<String> inferred_name_; | 
| + AstProperties ast_properties_; | 
| int materialized_literal_count_; | 
| int expected_property_count_; | 
| @@ -1782,17 +1894,20 @@ class FunctionLiteral: public Expression { | 
| class SharedFunctionInfoLiteral: public Expression { | 
| public: | 
| - SharedFunctionInfoLiteral( | 
| - Isolate* isolate, | 
| - Handle<SharedFunctionInfo> shared_function_info) | 
| - : Expression(isolate), shared_function_info_(shared_function_info) { } | 
| - | 
| DECLARE_NODE_TYPE(SharedFunctionInfoLiteral) | 
| Handle<SharedFunctionInfo> shared_function_info() const { | 
| return shared_function_info_; | 
| } | 
| - virtual bool IsInlineable() const; | 
| + | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| + SharedFunctionInfoLiteral( | 
| + Isolate* isolate, | 
| + Handle<SharedFunctionInfo> shared_function_info) | 
| + : Expression(isolate), | 
| + shared_function_info_(shared_function_info) { } | 
| private: | 
| Handle<SharedFunctionInfo> shared_function_info_; | 
| @@ -1801,9 +1916,12 @@ class SharedFunctionInfoLiteral: public Expression { | 
| class ThisFunction: public Expression { | 
| public: | 
| - explicit ThisFunction(Isolate* isolate) : Expression(isolate) {} | 
| DECLARE_NODE_TYPE(ThisFunction) | 
| - virtual bool IsInlineable() const; | 
| + | 
| + protected: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| + explicit ThisFunction(Isolate* isolate): Expression(isolate) {} | 
| }; | 
| @@ -2207,6 +2325,342 @@ class AstVisitor BASE_EMBEDDED { | 
| }; | 
| +// ---------------------------------------------------------------------------- | 
| +// Construction time visitor. | 
| + | 
| +class AstConstructionVisitor BASE_EMBEDDED { | 
| + public: | 
| + AstConstructionVisitor() { } | 
| + | 
| + AstProperties* ast_properties() { return &properties_; } | 
| + | 
| + private: | 
| + template<class> friend class AstNodeFactory; | 
| + | 
| + // Node visitors. | 
| +#define DEF_VISIT(type) \ | 
| + void Visit##type(type* node); | 
| + AST_NODE_LIST(DEF_VISIT) | 
| +#undef DEF_VISIT | 
| + | 
| + void increase_node_count() { properties_.add_node_count(1); } | 
| + void add_flag(AstPropertiesFlag flag) { properties_.flags()->Add(flag); } | 
| + | 
| + AstProperties properties_; | 
| +}; | 
| + | 
| + | 
| +class AstNullVisitor BASE_EMBEDDED { | 
| + public: | 
| + // Node visitors. | 
| +#define DEF_VISIT(type) \ | 
| + void Visit##type(type* node) {} | 
| + AST_NODE_LIST(DEF_VISIT) | 
| +#undef DEF_VISIT | 
| +}; | 
| + | 
| + | 
| + | 
| +// ---------------------------------------------------------------------------- | 
| +// AstNode factory | 
| + | 
| +template<class Visitor> | 
| +class AstNodeFactory BASE_EMBEDDED { | 
| + public: | 
| + explicit AstNodeFactory(Isolate* isolate) | 
| + : isolate_(isolate), | 
| + zone_(isolate_->zone()) { } | 
| + | 
| + Visitor* visitor() { return &visitor_; } | 
| + | 
| +#define VISIT_AND_RETURN(NodeType, node) \ | 
| + visitor_.Visit##NodeType((node)); \ | 
| + return node; | 
| + | 
| + Block* NewBlock(ZoneStringList* labels, | 
| + int capacity, | 
| + bool is_initializer_block) { | 
| + Block* block = new(zone_) Block( | 
| + isolate_, labels, capacity, is_initializer_block); | 
| + VISIT_AND_RETURN(Block, block) | 
| + } | 
| + | 
| + Declaration* NewDeclaration(VariableProxy* proxy, | 
| + VariableMode mode, | 
| + FunctionLiteral* fun, | 
| + Scope* scope) { | 
| + Declaration* decl = new(zone_) Declaration(proxy, mode, fun, scope); | 
| + VISIT_AND_RETURN(Declaration, decl) | 
| + } | 
| + | 
| +#define STATEMENT_WITH_LABELS(NodeType) \ | 
| + NodeType* New##NodeType(ZoneStringList* labels) { \ | 
| + NodeType* stmt = new(zone_) NodeType(isolate_, labels); \ | 
| + VISIT_AND_RETURN(NodeType, stmt); \ | 
| + } | 
| + STATEMENT_WITH_LABELS(DoWhileStatement) | 
| + STATEMENT_WITH_LABELS(WhileStatement) | 
| + STATEMENT_WITH_LABELS(ForStatement) | 
| + STATEMENT_WITH_LABELS(ForInStatement) | 
| + STATEMENT_WITH_LABELS(SwitchStatement) | 
| +#undef STATEMENT_WITH_LABELS | 
| + | 
| + ExpressionStatement* NewExpressionStatement(Expression* expression) { | 
| + ExpressionStatement* stmt = new(zone_) ExpressionStatement(expression); | 
| + VISIT_AND_RETURN(ExpressionStatement, stmt) | 
| + } | 
| + | 
| + ContinueStatement* NewContinueStatement(IterationStatement* target) { | 
| + ContinueStatement* stmt = new(zone_) ContinueStatement(target); | 
| + VISIT_AND_RETURN(ContinueStatement, stmt) | 
| + } | 
| + | 
| + BreakStatement* NewBreakStatement(BreakableStatement* target) { | 
| + BreakStatement* stmt = new(zone_) BreakStatement(target); | 
| + VISIT_AND_RETURN(BreakStatement, stmt) | 
| + } | 
| + | 
| + ReturnStatement* NewReturnStatement(Expression* expression) { | 
| + ReturnStatement* stmt = new(zone_) ReturnStatement(expression); | 
| + VISIT_AND_RETURN(ReturnStatement, stmt) | 
| + } | 
| + | 
| + WithStatement* NewWithStatement(Expression* expression, | 
| + Statement* statement) { | 
| + WithStatement* stmt = new(zone_) WithStatement(expression, statement); | 
| + VISIT_AND_RETURN(WithStatement, stmt) | 
| + } | 
| + | 
| + IfStatement* NewIfStatement(Expression* condition, | 
| + Statement* then_statement, | 
| + Statement* else_statement) { | 
| + IfStatement* stmt = new(zone_) IfStatement( | 
| + isolate_, condition, then_statement, else_statement); | 
| + VISIT_AND_RETURN(IfStatement, stmt) | 
| + } | 
| + | 
| + TryCatchStatement* NewTryCatchStatement(int index, | 
| + Block* try_block, | 
| + Scope* scope, | 
| + Variable* variable, | 
| + Block* catch_block) { | 
| + TryCatchStatement* stmt = new(zone_) TryCatchStatement( | 
| + index, try_block, scope, variable, catch_block); | 
| + VISIT_AND_RETURN(TryCatchStatement, stmt) | 
| + } | 
| + | 
| + TryFinallyStatement* NewTryFinallyStatement(int index, | 
| + Block* try_block, | 
| + Block* finally_block) { | 
| + TryFinallyStatement* stmt = | 
| + new(zone_) TryFinallyStatement(index, try_block, finally_block); | 
| + VISIT_AND_RETURN(TryFinallyStatement, stmt) | 
| + } | 
| + | 
| + DebuggerStatement* NewDebuggerStatement() { | 
| + DebuggerStatement* stmt = new(zone_) DebuggerStatement(); | 
| + VISIT_AND_RETURN(DebuggerStatement, stmt) | 
| + } | 
| + | 
| + EmptyStatement* NewEmptyStatement() { | 
| + return new(zone_) EmptyStatement(); | 
| + } | 
| + | 
| + Literal* NewLiteral(Handle<Object> handle) { | 
| + Literal* lit = new(zone_) Literal(isolate_, handle); | 
| + VISIT_AND_RETURN(Literal, lit) | 
| + } | 
| + | 
| + Literal* NewNumberLiteral(double number) { | 
| + return NewLiteral(isolate_->factory()->NewNumber(number, TENURED)); | 
| + } | 
| + | 
| + ObjectLiteral* NewObjectLiteral( | 
| + Handle<FixedArray> constant_properties, | 
| + ZoneList<ObjectLiteral::Property*>* properties, | 
| + int literal_index, | 
| + bool is_simple, | 
| + bool fast_elements, | 
| + int depth, | 
| + bool has_function) { | 
| + ObjectLiteral* lit = new(zone_) ObjectLiteral( | 
| + isolate_, constant_properties, properties, literal_index, | 
| + is_simple, fast_elements, depth, has_function); | 
| + VISIT_AND_RETURN(ObjectLiteral, lit) | 
| + } | 
| + | 
| + ObjectLiteral::Property* NewObjectLiteralProperty(bool is_getter, | 
| + FunctionLiteral* value) { | 
| + ObjectLiteral::Property* prop = | 
| + new(zone_) ObjectLiteral::Property(is_getter, value); | 
| + prop->set_key(NewLiteral(value->name())); | 
| + return prop; // Not an AST node, will not be visited. | 
| + } | 
| + | 
| + RegExpLiteral* NewRegExpLiteral(Handle<String> pattern, | 
| + Handle<String> flags, | 
| + int literal_index) { | 
| + RegExpLiteral* lit = | 
| + new(zone_) RegExpLiteral(isolate_, pattern, flags, literal_index); | 
| + VISIT_AND_RETURN(RegExpLiteral, lit); | 
| + } | 
| + | 
| + ArrayLiteral* NewArrayLiteral(Handle<FixedArray> constant_elements, | 
| + ZoneList<Expression*>* values, | 
| + int literal_index, | 
| + bool is_simple, | 
| + int depth) { | 
| + ArrayLiteral* lit = new(zone_) ArrayLiteral( | 
| + isolate_, constant_elements, values, literal_index, is_simple, depth); | 
| + VISIT_AND_RETURN(ArrayLiteral, lit) | 
| + } | 
| + | 
| + VariableProxy* NewVariableProxy(Variable* var) { | 
| + VariableProxy* proxy = new(zone_) VariableProxy(isolate_, var); | 
| + VISIT_AND_RETURN(VariableProxy, proxy) | 
| + } | 
| + | 
| + VariableProxy* NewVariableProxy(Handle<String> name, | 
| + bool is_this, | 
| + int position = RelocInfo::kNoPosition) { | 
| + VariableProxy* proxy = | 
| + new(zone_) VariableProxy(isolate_, name, is_this, position); | 
| + VISIT_AND_RETURN(VariableProxy, proxy) | 
| + } | 
| + | 
| + Property* NewProperty(Expression* obj, Expression* key, int pos) { | 
| + Property* prop = new(zone_) Property(isolate_, obj, key, pos); | 
| + VISIT_AND_RETURN(Property, prop) | 
| + } | 
| + | 
| + Call* NewCall(Expression* expression, | 
| + ZoneList<Expression*>* arguments, | 
| + int pos) { | 
| + Call* call = new(zone_) Call(isolate_, expression, arguments, pos); | 
| + VISIT_AND_RETURN(Call, call) | 
| + } | 
| + | 
| + CallNew* NewCallNew(Expression* expression, | 
| + ZoneList<Expression*>* arguments, | 
| + int pos) { | 
| + CallNew* call = new(zone_) CallNew(isolate_, expression, arguments, pos); | 
| + VISIT_AND_RETURN(CallNew, call) | 
| + } | 
| + | 
| + CallRuntime* NewCallRuntime(Handle<String> name, | 
| + const Runtime::Function* function, | 
| + ZoneList<Expression*>* arguments) { | 
| + CallRuntime* call = | 
| + new(zone_) CallRuntime(isolate_, name, function, arguments); | 
| + VISIT_AND_RETURN(CallRuntime, call) | 
| + } | 
| + | 
| + UnaryOperation* NewUnaryOperation(Token::Value op, | 
| + Expression* expression, | 
| + int pos) { | 
| + UnaryOperation* node = | 
| + new(zone_) UnaryOperation(isolate_, op, expression, pos); | 
| + VISIT_AND_RETURN(UnaryOperation, node) | 
| + } | 
| + | 
| + BinaryOperation* NewBinaryOperation(Token::Value op, | 
| + Expression* left, | 
| + Expression* right, | 
| + int pos) { | 
| + BinaryOperation* node = | 
| + new(zone_) BinaryOperation(isolate_, op, left, right, pos); | 
| + VISIT_AND_RETURN(BinaryOperation, node) | 
| + } | 
| + | 
| + CountOperation* NewCountOperation(Token::Value op, | 
| + bool is_prefix, | 
| + Expression* expr, | 
| + int pos) { | 
| + CountOperation* node = | 
| + new(zone_) CountOperation(isolate_, op, is_prefix, expr, pos); | 
| + VISIT_AND_RETURN(CountOperation, node) | 
| + } | 
| + | 
| + CompareOperation* NewCompareOperation(Token::Value op, | 
| + Expression* left, | 
| + Expression* right, | 
| + int pos) { | 
| + CompareOperation* node = | 
| + new(zone_) CompareOperation(isolate_, op, left, right, pos); | 
| + VISIT_AND_RETURN(CompareOperation, node) | 
| + } | 
| + | 
| + Conditional* NewConditional(Expression* condition, | 
| + Expression* then_expression, | 
| + Expression* else_expression, | 
| + int then_expression_position, | 
| + int else_expression_position) { | 
| + Conditional* cond = new(zone_) Conditional( | 
| + isolate_, condition, then_expression, else_expression, | 
| + then_expression_position, else_expression_position); | 
| + VISIT_AND_RETURN(Conditional, cond) | 
| + } | 
| + | 
| + Assignment* NewAssignment(Token::Value op, | 
| + Expression* target, | 
| + Expression* value, | 
| + int pos) { | 
| + Assignment* assign = | 
| + new(zone_) Assignment(isolate_, op, target, value, pos); | 
| + assign->Init(isolate_, this); | 
| + VISIT_AND_RETURN(Assignment, assign) | 
| + } | 
| + | 
| + Throw* NewThrow(Expression* exception, int pos) { | 
| + Throw* t = new(zone_) Throw(isolate_, exception, pos); | 
| + VISIT_AND_RETURN(Throw, t) | 
| + } | 
| + | 
| + FunctionLiteral* 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, | 
| + bool has_duplicate_parameters, | 
| + FunctionLiteral::Type type, | 
| + bool visit_with_visitor) { | 
| + FunctionLiteral* lit = new(zone_) FunctionLiteral( | 
| + isolate_, name, scope, body, | 
| + materialized_literal_count, expected_property_count, handler_count, | 
| + has_only_simple_this_property_assignments, this_property_assignments, | 
| + parameter_count, type, has_duplicate_parameters); | 
| + if (visit_with_visitor) { | 
| + visitor_.VisitFunctionLiteral(lit); | 
| + } | 
| + return lit; | 
| + } | 
| + | 
| + SharedFunctionInfoLiteral* NewSharedFunctionInfoLiteral( | 
| + Handle<SharedFunctionInfo> shared_function_info) { | 
| + SharedFunctionInfoLiteral* lit = | 
| + new(zone_) SharedFunctionInfoLiteral(isolate_, shared_function_info); | 
| + VISIT_AND_RETURN(SharedFunctionInfoLiteral, lit) | 
| + } | 
| + | 
| + ThisFunction* NewThisFunction() { | 
| + ThisFunction* fun = new(zone_) ThisFunction(isolate_); | 
| + VISIT_AND_RETURN(ThisFunction, fun) | 
| + } | 
| + | 
| +#undef VISIT_AND_RETURN | 
| + | 
| + private: | 
| + Isolate* isolate_; | 
| + Zone* zone_; | 
| + Visitor visitor_; | 
| +}; | 
| + | 
| + | 
| } } // namespace v8::internal | 
| #endif // V8_AST_H_ |