Index: src/ast.cc |
diff --git a/src/ast.cc b/src/ast.cc |
index 811193b49bde08c34da5f54648a90b0542c4ab89..44182d6ae6b5a3e08a819fe0b097dfa1f957924e 100644 |
--- a/src/ast.cc |
+++ b/src/ast.cc |
@@ -76,7 +76,8 @@ VariableProxy::VariableProxy(Isolate* isolate, Variable* var) |
is_this_(var->is_this()), |
is_trivial_(false), |
is_lvalue_(false), |
- position_(RelocInfo::kNoPosition) { |
+ position_(RelocInfo::kNoPosition), |
+ ast_properties_(NULL) { |
BindTo(var); |
} |
@@ -91,7 +92,8 @@ VariableProxy::VariableProxy(Isolate* isolate, |
is_this_(is_this), |
is_trivial_(false), |
is_lvalue_(false), |
- position_(position) { |
+ position_(position), |
+ ast_properties_(NULL) { |
// Names must be canonicalized for fast equality checks. |
ASSERT(name->IsSymbol()); |
} |
@@ -108,6 +110,9 @@ void VariableProxy::BindTo(Variable* var) { |
// in JS. Sigh... |
var_ = var; |
var->set_is_used(true); |
+ if (ast_properties_!= NULL) { |
+ ast_properties_->RevisitVariableProxy(this); |
+ } |
} |
@@ -115,7 +120,8 @@ Assignment::Assignment(Isolate* isolate, |
Token::Value op, |
Expression* target, |
Expression* value, |
- int pos) |
+ int pos, |
+ AstNodeFactory* factory) |
: Expression(isolate), |
op_(op), |
target_(target), |
@@ -130,11 +136,7 @@ Assignment::Assignment(Isolate* isolate, |
ASSERT(Token::IsAssignmentOp(op)); |
if (is_compound()) { |
binary_operation_ = |
- new(isolate->zone()) BinaryOperation(isolate, |
- binary_op(), |
- target, |
- value, |
- pos + 1); |
+ factory->NewBinaryOperation(binary_op(), target, value, pos + 1); |
compound_load_id_ = GetNextId(isolate); |
} |
} |
@@ -179,6 +181,16 @@ LanguageMode FunctionLiteral::language_mode() const { |
} |
+bool FunctionLiteral::ShouldSelfOptimize() { |
+ return !ast_properties()->flags()->Contains(kDontSelfOptimize); |
+} |
+ |
+ |
+int FunctionLiteral::AstNodeCount() { |
+ return ast_properties()->node_count(); |
+} |
+ |
+ |
ObjectLiteral::Property::Property(Literal* key, Expression* value) { |
emit_store_ = true; |
key_ = key; |
@@ -196,10 +208,11 @@ ObjectLiteral::Property::Property(Literal* key, Expression* value) { |
} |
-ObjectLiteral::Property::Property(bool is_getter, FunctionLiteral* value) { |
- Isolate* isolate = Isolate::Current(); |
+ObjectLiteral::Property::Property(bool is_getter, |
+ FunctionLiteral* value, |
+ AstNodeFactory* factory) { |
emit_store_ = true; |
- key_ = new(isolate->zone()) Literal(isolate, value->name()); |
+ key_ = factory->NewLiteral(value->name()); |
value_ = value; |
kind_ = is_getter ? GETTER : SETTER; |
} |
@@ -431,223 +444,6 @@ bool Declaration::IsInlineable() const { |
} |
-bool TargetCollector::IsInlineable() const { |
- UNREACHABLE(); |
- return false; |
-} |
- |
- |
-bool ForInStatement::IsInlineable() const { |
- return false; |
-} |
- |
- |
-bool WithStatement::IsInlineable() const { |
- return false; |
-} |
- |
- |
-bool SwitchStatement::IsInlineable() const { |
- return false; |
-} |
- |
- |
-bool TryStatement::IsInlineable() const { |
- return false; |
-} |
- |
- |
-bool TryCatchStatement::IsInlineable() const { |
- return false; |
-} |
- |
- |
-bool TryFinallyStatement::IsInlineable() const { |
- return false; |
-} |
- |
- |
-bool DebuggerStatement::IsInlineable() const { |
- return false; |
-} |
- |
- |
-bool Throw::IsInlineable() const { |
- return exception()->IsInlineable(); |
-} |
- |
- |
-bool MaterializedLiteral::IsInlineable() const { |
- // TODO(1322): Allow materialized literals. |
- return false; |
-} |
- |
- |
-bool FunctionLiteral::IsInlineable() const { |
- // TODO(1322): Allow materialized literals. |
- return false; |
-} |
- |
- |
-bool ThisFunction::IsInlineable() const { |
- return true; |
-} |
- |
- |
-bool SharedFunctionInfoLiteral::IsInlineable() const { |
- return false; |
-} |
- |
- |
-bool ForStatement::IsInlineable() const { |
- return (init() == NULL || init()->IsInlineable()) |
- && (cond() == NULL || cond()->IsInlineable()) |
- && (next() == NULL || next()->IsInlineable()) |
- && body()->IsInlineable(); |
-} |
- |
- |
-bool WhileStatement::IsInlineable() const { |
- return cond()->IsInlineable() |
- && body()->IsInlineable(); |
-} |
- |
- |
-bool DoWhileStatement::IsInlineable() const { |
- return cond()->IsInlineable() |
- && body()->IsInlineable(); |
-} |
- |
- |
-bool ContinueStatement::IsInlineable() const { |
- return true; |
-} |
- |
- |
-bool BreakStatement::IsInlineable() const { |
- return true; |
-} |
- |
- |
-bool EmptyStatement::IsInlineable() const { |
- return true; |
-} |
- |
- |
-bool Literal::IsInlineable() const { |
- return true; |
-} |
- |
- |
-bool Block::IsInlineable() const { |
- const int count = statements_.length(); |
- for (int i = 0; i < count; ++i) { |
- if (!statements_[i]->IsInlineable()) return false; |
- } |
- return true; |
-} |
- |
- |
-bool ExpressionStatement::IsInlineable() const { |
- return expression()->IsInlineable(); |
-} |
- |
- |
-bool IfStatement::IsInlineable() const { |
- return condition()->IsInlineable() |
- && then_statement()->IsInlineable() |
- && else_statement()->IsInlineable(); |
-} |
- |
- |
-bool ReturnStatement::IsInlineable() const { |
- return expression()->IsInlineable(); |
-} |
- |
- |
-bool Conditional::IsInlineable() const { |
- return condition()->IsInlineable() && then_expression()->IsInlineable() && |
- else_expression()->IsInlineable(); |
-} |
- |
- |
-bool VariableProxy::IsInlineable() const { |
- return var()->IsUnallocated() |
- || var()->IsStackAllocated() |
- || var()->IsContextSlot(); |
-} |
- |
- |
-bool Assignment::IsInlineable() const { |
- return target()->IsInlineable() && value()->IsInlineable(); |
-} |
- |
- |
-bool Property::IsInlineable() const { |
- return obj()->IsInlineable() && key()->IsInlineable(); |
-} |
- |
- |
-bool Call::IsInlineable() const { |
- if (!expression()->IsInlineable()) return false; |
- const int count = arguments()->length(); |
- for (int i = 0; i < count; ++i) { |
- if (!arguments()->at(i)->IsInlineable()) return false; |
- } |
- return true; |
-} |
- |
- |
-bool CallNew::IsInlineable() const { |
- if (!expression()->IsInlineable()) return false; |
- const int count = arguments()->length(); |
- for (int i = 0; i < count; ++i) { |
- if (!arguments()->at(i)->IsInlineable()) return false; |
- } |
- return true; |
-} |
- |
- |
-bool CallRuntime::IsInlineable() const { |
- // Don't try to inline JS runtime calls because we don't (currently) even |
- // optimize them. |
- if (is_jsruntime()) return false; |
- // Don't inline the %_ArgumentsLength or %_Arguments because their |
- // implementation will not work. There is no stack frame to get them |
- // from. |
- if (function()->intrinsic_type == Runtime::INLINE && |
- (name()->IsEqualTo(CStrVector("_ArgumentsLength")) || |
- name()->IsEqualTo(CStrVector("_Arguments")))) { |
- return false; |
- } |
- const int count = arguments()->length(); |
- for (int i = 0; i < count; ++i) { |
- if (!arguments()->at(i)->IsInlineable()) return false; |
- } |
- return true; |
-} |
- |
- |
-bool UnaryOperation::IsInlineable() const { |
- return expression()->IsInlineable(); |
-} |
- |
- |
-bool BinaryOperation::IsInlineable() const { |
- return left()->IsInlineable() && right()->IsInlineable(); |
-} |
- |
- |
-bool CompareOperation::IsInlineable() const { |
- return left()->IsInlineable() && right()->IsInlineable(); |
-} |
- |
- |
-bool CountOperation::IsInlineable() const { |
- return expression()->IsInlineable(); |
-} |
- |
- |
// ---------------------------------------------------------------------------- |
// Recording of type feedback |
@@ -1215,4 +1011,608 @@ CaseClause::CaseClause(Isolate* isolate, |
entry_id_(AstNode::GetNextId(isolate)) { |
} |
+ |
+AstProperties::~AstProperties() {} |
+ |
+ |
+void AstConstructionVisitor::VisitDeclaration(Declaration* node) { |
+ increase_node_count(); |
+ // TODO(jkummerow): Inlineable iff |
+ // proxy()->var()->IsStackAllocated() && fun() == NULL; |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitBlock(Block* node) { |
+ increase_node_count(); |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitExpressionStatement( |
+ ExpressionStatement* node) { |
+ increase_node_count(); |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitEmptyStatement(EmptyStatement* node) { |
+ increase_node_count(); |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitIfStatement(IfStatement* node) { |
+ increase_node_count(); |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitContinueStatement(ContinueStatement* node) { |
+ increase_node_count(); |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitBreakStatement(BreakStatement* node) { |
+ increase_node_count(); |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitReturnStatement(ReturnStatement* node) { |
+ increase_node_count(); |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitWithStatement(WithStatement* node) { |
+ increase_node_count(); |
+ add_flag(kDontCrankshaft); |
+ add_flag(kDontInline); |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitSwitchStatement(SwitchStatement* node) { |
+ increase_node_count(); |
+ add_flag(kDontInline); |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitDoWhileStatement(DoWhileStatement* node) { |
+ increase_node_count(); |
+ add_flag(kDontSelfOptimize); |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitWhileStatement(WhileStatement* node) { |
+ increase_node_count(); |
+ add_flag(kDontSelfOptimize); |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitForStatement(ForStatement* node) { |
+ increase_node_count(); |
+ add_flag(kDontSelfOptimize); |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitForInStatement(ForInStatement* node) { |
+ increase_node_count(); |
+ add_flag(kDontCrankshaft); |
+ add_flag(kDontInline); |
+ add_flag(kDontSelfOptimize); |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitTryCatchStatement(TryCatchStatement* node) { |
+ increase_node_count(); |
+ add_flag(kDontCrankshaft); |
+ add_flag(kDontInline); |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitTryFinallyStatement( |
+ TryFinallyStatement* node) { |
+ increase_node_count(); |
+ add_flag(kDontCrankshaft); |
+ add_flag(kDontInline); |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitDebuggerStatement(DebuggerStatement* node) { |
+ increase_node_count(); |
+ add_flag(kDontCrankshaft); |
+ add_flag(kDontInline); |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitFunctionLiteral(FunctionLiteral* node) { |
+ increase_node_count(); |
+ add_flag(kDontInline); |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitSharedFunctionInfoLiteral( |
+ SharedFunctionInfoLiteral* node) { |
+ increase_node_count(); |
+ add_flag(kDontCrankshaft); |
+ add_flag(kDontInline); |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitConditional(Conditional* node) { |
+ increase_node_count(); |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitVariableProxy(VariableProxy* node) { |
+ increase_node_count(); |
+ properties_->RevisitVariableProxy(node); |
+} |
+ |
+ |
+void AstProperties::RevisitVariableProxy(VariableProxy* node) { |
+ node->set_ast_properties(this); |
+ Variable* var = node->var(); |
+ if (var != NULL && |
+ !var->IsUnallocated() && |
+ !var->IsStackAllocated() && |
+ !var->IsContextSlot()) { |
+ flags_.Add(kDontInline); |
+ } |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitLiteral(Literal* node) { |
+ increase_node_count(); |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitRegExpLiteral(RegExpLiteral* node) { |
+ increase_node_count(); |
+ add_flag(kDontInline); // TODO(1322): Allow materialized literals. |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitObjectLiteral(ObjectLiteral* node) { |
+ increase_node_count(); |
+ add_flag(kDontInline); // TODO(1322): Allow materialized literals. |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitArrayLiteral(ArrayLiteral* node) { |
+ increase_node_count(); |
+ add_flag(kDontInline); // TODO(1322): Allow materialized literals. |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitAssignment(Assignment* node) { |
+ increase_node_count(); |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitThrow(Throw* node) { |
+ increase_node_count(); |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitProperty(Property* node) { |
+ increase_node_count(); |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitCall(Call* node) { |
+ increase_node_count(); |
+ add_flag(kDontSelfOptimize); |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitCallNew(CallNew* node) { |
+ increase_node_count(); |
+ add_flag(kDontSelfOptimize); |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitCallRuntime(CallRuntime* node) { |
+ increase_node_count(); |
+ add_flag(kDontSelfOptimize); |
+ if (node->is_jsruntime()) { |
+ // Don't try to inline JS runtime calls because we don't (currently) even |
+ // optimize them. |
+ add_flag(kDontInline); |
+ } else if (node->function()->intrinsic_type == Runtime::INLINE && |
+ (node->name()->IsEqualTo(CStrVector("_ArgumentsLength")) || |
+ node->name()->IsEqualTo(CStrVector("_Arguments")))) { |
+ // Don't inline the %_ArgumentsLength or %_Arguments because their |
+ // implementation will not work. There is no stack frame to get them |
+ // from. |
+ add_flag(kDontInline); |
+ } |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitUnaryOperation(UnaryOperation* node) { |
+ increase_node_count(); |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitCountOperation(CountOperation* node) { |
+ increase_node_count(); |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitBinaryOperation(BinaryOperation* node) { |
+ increase_node_count(); |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitCompareOperation(CompareOperation* node) { |
+ increase_node_count(); |
+} |
+ |
+ |
+void AstConstructionVisitor::VisitThisFunction(ThisFunction* node) { |
+ increase_node_count(); |
+} |
+ |
+ |
+Block* AstNodeFactory::NewBlock(ZoneStringList* labels, |
+ int capacity, |
+ bool is_initializer_block) { |
+ Block* block = new(zone_) Block( |
+ isolate_, labels, capacity, is_initializer_block); |
+ Visit(block); |
+ return block; |
+} |
+ |
+ |
+Declaration* AstNodeFactory::NewDeclaration(VariableProxy* proxy, |
+ VariableMode mode, |
+ FunctionLiteral* fun, |
+ Scope* scope) { |
+ Declaration* decl = new(zone_) Declaration(proxy, mode, fun, scope); |
+ Visit(decl); |
+ return decl; |
+} |
+ |
+ |
+DoWhileStatement* AstNodeFactory::NewDoWhileStatement(ZoneStringList* labels) { |
+ DoWhileStatement* stmt = new(zone_) DoWhileStatement(isolate_, labels); |
+ Visit(stmt); |
+ return stmt; |
+} |
+ |
+ |
+WhileStatement* AstNodeFactory::NewWhileStatement(ZoneStringList* labels) { |
+ WhileStatement* stmt = new(zone_) WhileStatement(isolate_, labels); |
+ Visit(stmt); |
+ return stmt; |
+} |
+ |
+ |
+ForStatement* AstNodeFactory::NewForStatement(ZoneStringList* labels) { |
+ ForStatement* stmt = new(zone_) ForStatement(isolate_, labels); |
+ Visit(stmt); |
+ return stmt; |
+} |
+ |
+ |
+ForInStatement* AstNodeFactory::NewForInStatement(ZoneStringList* labels) { |
+ ForInStatement* stmt = new(zone_) ForInStatement(isolate_, labels); |
+ Visit(stmt); |
+ return stmt; |
+} |
+ |
+ |
+ExpressionStatement* AstNodeFactory::NewExpressionStatement( |
+ Expression* expression) { |
+ ExpressionStatement* stmt = new(zone_) ExpressionStatement(expression); |
+ Visit(stmt); |
+ return stmt; |
+} |
+ |
+ |
+ContinueStatement* AstNodeFactory::NewContinueStatement( |
+ IterationStatement* target) { |
+ ContinueStatement* stmt = new(zone_) ContinueStatement(target); |
+ Visit(stmt); |
+ return stmt; |
+} |
+ |
+ |
+BreakStatement* AstNodeFactory::NewBreakStatement(BreakableStatement* target) { |
+ BreakStatement* stmt = new(zone_) BreakStatement(target); |
+ Visit(stmt); |
+ return stmt; |
+} |
+ |
+ |
+ReturnStatement* AstNodeFactory::NewReturnStatement(Expression* expression) { |
+ ReturnStatement* stmt = new(zone_) ReturnStatement(expression); |
+ Visit(stmt); |
+ return stmt; |
+} |
+ |
+ |
+WithStatement* AstNodeFactory::NewWithStatement(Expression* expression, |
+ Statement* statement) { |
+ WithStatement* stmt = new(zone_) WithStatement(expression, statement); |
+ Visit(stmt); |
+ return stmt; |
+} |
+ |
+ |
+SwitchStatement* AstNodeFactory::NewSwitchStatement(ZoneStringList* labels) { |
+ SwitchStatement* stmt = new(zone_) SwitchStatement(isolate_, labels); |
+ Visit(stmt); |
+ return stmt; |
+} |
+ |
+ |
+IfStatement* AstNodeFactory::NewIfStatement(Expression* condition, |
+ Statement* then_statement, |
+ Statement* else_statement) { |
+ IfStatement* stmt = new(zone_) IfStatement( |
+ isolate_, condition, then_statement, else_statement); |
+ Visit(stmt); |
+ return stmt; |
+} |
+ |
+ |
+TryCatchStatement* AstNodeFactory::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(stmt); |
+ return stmt; |
+} |
+ |
+ |
+TryFinallyStatement* AstNodeFactory::NewTryFinallyStatement( |
+ int index, |
+ Block* try_block, |
+ Block* finally_block) { |
+ TryFinallyStatement* stmt = |
+ new(zone_) TryFinallyStatement(index, try_block, finally_block); |
+ Visit(stmt); |
+ return stmt; |
+} |
+ |
+ |
+DebuggerStatement* AstNodeFactory::NewDebuggerStatement() { |
+ DebuggerStatement* stmt = new(zone_) DebuggerStatement(); |
+ Visit(stmt); |
+ return stmt; |
+} |
+ |
+ |
+EmptyStatement* AstNodeFactory::NewEmptyStatement() { |
+ static EmptyStatement* empty = ::new EmptyStatement(); |
+ return empty; |
+} |
+ |
+ |
+Literal* AstNodeFactory::NewLiteral(Handle<Object> handle) { |
+ Literal* lit = new(zone_) Literal(isolate_, handle); |
+ Visit(lit); |
+ return lit; |
+} |
+ |
+ |
+Literal* AstNodeFactory::NewNumberLiteral(double number) { |
+ return NewLiteral(isolate_->factory()->NewNumber(number, TENURED)); |
+} |
+ |
+ |
+ObjectLiteral* AstNodeFactory::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(lit); |
+ return lit; |
+} |
+ |
+ |
+RegExpLiteral* AstNodeFactory::NewRegExpLiteral(Handle<String> pattern, |
+ Handle<String> flags, |
+ int literal_index) { |
+ RegExpLiteral* lit = |
+ new(zone_) RegExpLiteral(isolate_, pattern, flags, literal_index); |
+ Visit(lit); |
+ return lit; |
+} |
+ |
+ |
+ArrayLiteral* AstNodeFactory::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(lit); |
+ return lit; |
+} |
+ |
+ |
+VariableProxy* AstNodeFactory::NewVariableProxy(Variable* var) { |
+ VariableProxy* proxy = new(zone_) VariableProxy(isolate_, var); |
+ Visit(proxy); |
+ return proxy; |
+} |
+ |
+ |
+VariableProxy* AstNodeFactory::NewVariableProxy(Handle<String> name, |
+ bool is_this, |
+ int position) { |
+ VariableProxy* proxy = |
+ new(zone_) VariableProxy(isolate_, name, is_this, position); |
+ Visit(proxy); |
+ return proxy; |
+} |
+ |
+ |
+Property* AstNodeFactory::NewProperty(Expression* obj, |
+ Expression* key, |
+ int pos) { |
+ Property* prop = new(zone_) Property(isolate_, obj, key, pos); |
+ Visit(prop); |
+ return prop; |
+} |
+ |
+ |
+Call* AstNodeFactory::NewCall(Expression* expression, |
+ ZoneList<Expression*>* arguments, |
+ int pos) { |
+ Call* call = new(zone_) Call(isolate_, expression, arguments, pos); |
+ Visit(call); |
+ return call; |
+} |
+ |
+ |
+CallNew* AstNodeFactory::NewCallNew(Expression* expression, |
+ ZoneList<Expression*>* arguments, |
+ int pos) { |
+ CallNew* call = new(zone_) CallNew(isolate_, expression, arguments, pos); |
+ Visit(call); |
+ return call; |
+} |
+ |
+ |
+CallRuntime* AstNodeFactory::NewCallRuntime(Handle<String> name, |
+ const Runtime::Function* function, |
+ ZoneList<Expression*>* arguments) { |
+ CallRuntime* call = |
+ new(zone_) CallRuntime(isolate_, name, function, arguments); |
+ Visit(call); |
+ return call; |
+} |
+ |
+ |
+UnaryOperation* AstNodeFactory::NewUnaryOperation(Token::Value op, |
+ Expression* expression, |
+ int pos) { |
+ UnaryOperation* node = |
+ new(zone_) UnaryOperation(isolate_, op, expression, pos); |
+ Visit(node); |
+ return node; |
+} |
+ |
+ |
+BinaryOperation* AstNodeFactory::NewBinaryOperation(Token::Value op, |
+ Expression* left, |
+ Expression* right, |
+ int pos) { |
+ BinaryOperation* node = |
+ new(zone_) BinaryOperation(isolate_, op, left, right, pos); |
+ Visit(node); |
+ return node; |
+} |
+ |
+ |
+CountOperation* AstNodeFactory::NewCountOperation(Token::Value op, |
+ bool is_prefix, |
+ Expression* expr, |
+ int pos) { |
+ CountOperation* node = |
+ new(zone_) CountOperation(isolate_, op, is_prefix, expr, pos); |
+ Visit(node); |
+ return node; |
+} |
+ |
+ |
+CompareOperation* AstNodeFactory::NewCompareOperation(Token::Value op, |
+ Expression* left, |
+ Expression* right, |
+ int pos) { |
+ CompareOperation* node = |
+ new(zone_) CompareOperation(isolate_, op, left, right, pos); |
+ Visit(node); |
+ return node; |
+} |
+ |
+ |
+Conditional* AstNodeFactory::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(cond); |
+ return cond; |
+} |
+ |
+ |
+Assignment* AstNodeFactory::NewAssignment(Token::Value op, |
+ Expression* target, |
+ Expression* value, |
+ int pos) { |
+ Assignment* assign = |
+ new(zone_) Assignment(isolate_, op, target, value, pos, this); |
+ Visit(assign); |
+ return assign; |
+} |
+ |
+ |
+Throw* AstNodeFactory::NewThrow(Expression* exception, int pos) { |
+ Throw* t = new(zone_) Throw(isolate_, exception, pos); |
+ Visit(t); |
+ return t; |
+} |
+ |
+FunctionLiteral* AstNodeFactory::NewFunctionLiteral( |
+ Handle<String> name, |
+ Scope* scope, |
+ ZoneList<Statement*>* body, |
+ int materialized_literal_count, |
+ int expected_property_count, |
+ int handler_count, |
+ bool has_only_simple_this_property_assignments, |
+ Handle<FixedArray> this_property_assignments, |
+ int parameter_count, |
+ FunctionLiteral::Type type, |
+ bool has_duplicate_parameters, |
+ 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) { |
+ Visit(lit); |
+ } |
+ return lit; |
+} |
+ |
+ |
+SharedFunctionInfoLiteral* AstNodeFactory::NewSharedFunctionInfoLiteral( |
+ Handle<SharedFunctionInfo> shared_function_info) { |
+ SharedFunctionInfoLiteral* lit = |
+ new(zone_) SharedFunctionInfoLiteral(isolate_, shared_function_info); |
+ Visit(lit); |
+ return lit; |
+} |
+ |
+ |
+ThisFunction* AstNodeFactory::NewThisFunction() { |
+ ThisFunction* fun = new(zone_) ThisFunction(isolate_); |
+ Visit(fun); |
+ return fun; |
+} |
+ |
+ |
+void AstNodeFactory::Visit(AstNode* node) { |
+ AstConstructionVisitor* visitor = |
+ reinterpret_cast<AstConstructionVisitor*>(visitor_); |
+ if (visitor_ != NULL && visitor->properties() != NULL) { |
+ node->Accept(visitor_); |
+ } |
+} |
+ |
} } // namespace v8::internal |