Commit 98ac5d81 authored by kasperl@chromium.org's avatar kasperl@chromium.org

Introduce a new intermediate AST node for encapsulating the

increment part of a count operation.
Review URL: http://codereview.chromium.org/3150032

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5328 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 23d0abb0
...@@ -89,6 +89,7 @@ namespace internal { ...@@ -89,6 +89,7 @@ namespace internal {
V(CallNew) \ V(CallNew) \
V(CallRuntime) \ V(CallRuntime) \
V(UnaryOperation) \ V(UnaryOperation) \
V(IncrementOperation) \
V(CountOperation) \ V(CountOperation) \
V(BinaryOperation) \ V(BinaryOperation) \
V(CompareOperation) \ V(CompareOperation) \
...@@ -1248,31 +1249,50 @@ class BinaryOperation: public Expression { ...@@ -1248,31 +1249,50 @@ class BinaryOperation: public Expression {
}; };
class CountOperation: public Expression { class IncrementOperation: public Expression {
public: public:
CountOperation(bool is_prefix, Token::Value op, Expression* expression) IncrementOperation(Token::Value op, Expression* expr)
: is_prefix_(is_prefix), op_(op), expression_(expression) { : op_(op), expression_(expr) {
ASSERT(Token::IsCountOp(op)); ASSERT(Token::IsCountOp(op));
} }
Token::Value op() const { return op_; }
bool is_increment() { return op_ == Token::INC; }
Expression* expression() const { return expression_; }
virtual void Accept(AstVisitor* v);
private:
Token::Value op_;
Expression* expression_;
};
class CountOperation: public Expression {
public:
CountOperation(bool is_prefix, IncrementOperation* increment)
: is_prefix_(is_prefix), increment_(increment) { }
virtual void Accept(AstVisitor* v); virtual void Accept(AstVisitor* v);
virtual CountOperation* AsCountOperation() { return this; } virtual CountOperation* AsCountOperation() { return this; }
bool is_prefix() const { return is_prefix_; } bool is_prefix() const { return is_prefix_; }
bool is_postfix() const { return !is_prefix_; } bool is_postfix() const { return !is_prefix_; }
Token::Value op() const { return op_; }
Token::Value op() const { return increment_->op(); }
Token::Value binary_op() { Token::Value binary_op() {
return op_ == Token::INC ? Token::ADD : Token::SUB; return (op() == Token::INC) ? Token::ADD : Token::SUB;
} }
Expression* expression() const { return expression_; }
Expression* expression() const { return increment_->expression(); }
IncrementOperation* increment() const { return increment_; }
virtual void MarkAsStatement() { is_prefix_ = true; } virtual void MarkAsStatement() { is_prefix_ = true; }
private: private:
bool is_prefix_; bool is_prefix_;
Token::Value op_; IncrementOperation* increment_;
Expression* expression_;
}; };
......
...@@ -339,6 +339,11 @@ void CodeGenerator::ProcessDeclarations(ZoneList<Declaration*>* declarations) { ...@@ -339,6 +339,11 @@ void CodeGenerator::ProcessDeclarations(ZoneList<Declaration*>* declarations) {
} }
void CodeGenerator::VisitIncrementOperation(IncrementOperation* expr) {
UNREACHABLE();
}
// List of special runtime calls which are generated inline. For some of these // List of special runtime calls which are generated inline. For some of these
// functions the code will be generated inline, and for others a call to a code // functions the code will be generated inline, and for others a call to a code
// stub will be inlined. // stub will be inlined.
......
...@@ -469,6 +469,12 @@ void AssignedVariablesAnalyzer::VisitUnaryOperation(UnaryOperation* expr) { ...@@ -469,6 +469,12 @@ void AssignedVariablesAnalyzer::VisitUnaryOperation(UnaryOperation* expr) {
} }
void AssignedVariablesAnalyzer::VisitIncrementOperation(
IncrementOperation* expr) {
UNREACHABLE();
}
void AssignedVariablesAnalyzer::VisitCountOperation(CountOperation* expr) { void AssignedVariablesAnalyzer::VisitCountOperation(CountOperation* expr) {
ASSERT(av_.IsEmpty()); ASSERT(av_.IsEmpty());
if (expr->is_prefix()) MarkIfTrivial(expr->expression()); if (expr->is_prefix()) MarkIfTrivial(expr->expression());
......
...@@ -215,6 +215,12 @@ void BreakableStatementChecker::VisitThrow(Throw* expr) { ...@@ -215,6 +215,12 @@ void BreakableStatementChecker::VisitThrow(Throw* expr) {
} }
void BreakableStatementChecker::VisitIncrementOperation(
IncrementOperation* expr) {
UNREACHABLE();
}
void BreakableStatementChecker::VisitProperty(Property* expr) { void BreakableStatementChecker::VisitProperty(Property* expr) {
// Property load is breakable. // Property load is breakable.
is_breakable_ = true; is_breakable_ = true;
...@@ -1014,6 +1020,11 @@ void FullCodeGenerator::VisitThrow(Throw* expr) { ...@@ -1014,6 +1020,11 @@ void FullCodeGenerator::VisitThrow(Throw* expr) {
} }
void FullCodeGenerator::VisitIncrementOperation(IncrementOperation* expr) {
UNREACHABLE();
}
int FullCodeGenerator::TryFinally::Exit(int stack_depth) { int FullCodeGenerator::TryFinally::Exit(int stack_depth) {
// The macros used here must preserve the result register. // The macros used here must preserve the result register.
__ Drop(stack_depth); __ Drop(stack_depth);
......
...@@ -3086,7 +3086,8 @@ Expression* Parser::ParseUnaryExpression(bool* ok) { ...@@ -3086,7 +3086,8 @@ Expression* Parser::ParseUnaryExpression(bool* ok) {
Handle<String> type = Factory::invalid_lhs_in_prefix_op_symbol(); Handle<String> type = Factory::invalid_lhs_in_prefix_op_symbol();
expression = NewThrowReferenceError(type); expression = NewThrowReferenceError(type);
} }
return NEW(CountOperation(true /* prefix */, op, expression)); IncrementOperation* increment = NEW(IncrementOperation(op, expression));
return NEW(CountOperation(true /* prefix */, increment));
} else { } else {
return ParsePostfixExpression(ok); return ParsePostfixExpression(ok);
...@@ -3109,7 +3110,8 @@ Expression* Parser::ParsePostfixExpression(bool* ok) { ...@@ -3109,7 +3110,8 @@ Expression* Parser::ParsePostfixExpression(bool* ok) {
expression = NewThrowReferenceError(type); expression = NewThrowReferenceError(type);
} }
Token::Value next = Next(); Token::Value next = Next();
expression = NEW(CountOperation(false /* postfix */, next, expression)); IncrementOperation* increment = NEW(IncrementOperation(next, expression));
expression = NEW(CountOperation(false /* postfix */, increment));
} }
return expression; return expression;
} }
......
...@@ -376,6 +376,11 @@ void PrettyPrinter::VisitUnaryOperation(UnaryOperation* node) { ...@@ -376,6 +376,11 @@ void PrettyPrinter::VisitUnaryOperation(UnaryOperation* node) {
} }
void PrettyPrinter::VisitIncrementOperation(IncrementOperation* node) {
UNREACHABLE();
}
void PrettyPrinter::VisitCountOperation(CountOperation* node) { void PrettyPrinter::VisitCountOperation(CountOperation* node) {
Print("("); Print("(");
if (node->is_prefix()) Print("%s", Token::String(node->op())); if (node->is_prefix()) Print("%s", Token::String(node->op()));
...@@ -1077,6 +1082,11 @@ void AstPrinter::VisitUnaryOperation(UnaryOperation* node) { ...@@ -1077,6 +1082,11 @@ void AstPrinter::VisitUnaryOperation(UnaryOperation* node) {
} }
void AstPrinter::VisitIncrementOperation(IncrementOperation* node) {
UNREACHABLE();
}
void AstPrinter::VisitCountOperation(CountOperation* node) { void AstPrinter::VisitCountOperation(CountOperation* node) {
EmbeddedVector<char, 128> buf; EmbeddedVector<char, 128> buf;
if (node->type()->IsKnown()) { if (node->type()->IsKnown()) {
...@@ -1477,6 +1487,11 @@ void JsonAstBuilder::VisitUnaryOperation(UnaryOperation* expr) { ...@@ -1477,6 +1487,11 @@ void JsonAstBuilder::VisitUnaryOperation(UnaryOperation* expr) {
} }
void JsonAstBuilder::VisitIncrementOperation(IncrementOperation* expr) {
UNREACHABLE();
}
void JsonAstBuilder::VisitCountOperation(CountOperation* expr) { void JsonAstBuilder::VisitCountOperation(CountOperation* expr) {
TagScope tag(this, "CountOperation"); TagScope tag(this, "CountOperation");
{ {
......
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
class AstOptimizer: public AstVisitor { class AstOptimizer: public AstVisitor {
public: public:
explicit AstOptimizer() : has_function_literal_(false) {} explicit AstOptimizer() : has_function_literal_(false) {}
...@@ -436,6 +435,11 @@ void AstOptimizer::VisitUnaryOperation(UnaryOperation* node) { ...@@ -436,6 +435,11 @@ void AstOptimizer::VisitUnaryOperation(UnaryOperation* node) {
} }
void AstOptimizer::VisitIncrementOperation(IncrementOperation* node) {
UNREACHABLE();
}
void AstOptimizer::VisitCountOperation(CountOperation* node) { void AstOptimizer::VisitCountOperation(CountOperation* node) {
// Count operations assume that they work on Smis. // Count operations assume that they work on Smis.
node->expression()->set_no_negative_zero(node->is_prefix() ? node->expression()->set_no_negative_zero(node->is_prefix() ?
...@@ -947,6 +951,11 @@ void Processor::VisitUnaryOperation(UnaryOperation* node) { ...@@ -947,6 +951,11 @@ void Processor::VisitUnaryOperation(UnaryOperation* node) {
} }
void Processor::VisitIncrementOperation(IncrementOperation* node) {
UNREACHABLE();
}
void Processor::VisitCountOperation(CountOperation* node) { void Processor::VisitCountOperation(CountOperation* node) {
USE(node); USE(node);
UNREACHABLE(); UNREACHABLE();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment