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_ |