Move the AstVisitor stack check from Accept to Visit.

The stack check has been moved from the Accept function dispatching on
the AST node type, earlier to the Visit function dispatching on the
visitor type.

This allows very simple non-recursive visitors (not taking extra
arguments or returning values) via the convention of calling "Visit"
if one wants the stack check and "Accept" if one does not.  Recursive
calls should all be via "Visit".

Review URL: http://codereview.chromium.org/1567007

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4320 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 155a9cdd
...@@ -48,10 +48,7 @@ Call Call::sentinel_(NULL, NULL, 0); ...@@ -48,10 +48,7 @@ Call Call::sentinel_(NULL, NULL, 0);
// All the Accept member functions for each syntax tree node type. // All the Accept member functions for each syntax tree node type.
#define DECL_ACCEPT(type) \ #define DECL_ACCEPT(type) \
void type::Accept(AstVisitor* v) { \ void type::Accept(AstVisitor* v) { v->Visit##type(this); }
if (v->CheckStackOverflow()) return; \
v->Visit##type(this); \
}
AST_NODE_LIST(DECL_ACCEPT) AST_NODE_LIST(DECL_ACCEPT)
#undef DECL_ACCEPT #undef DECL_ACCEPT
...@@ -241,6 +238,13 @@ bool Expression::GuaranteedSmiResult() { ...@@ -241,6 +238,13 @@ bool Expression::GuaranteedSmiResult() {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Implementation of AstVisitor // Implementation of AstVisitor
bool AstVisitor::CheckStackOverflow() {
if (stack_overflow_) return true;
StackLimitCheck check;
if (!check.HasOverflowed()) return false;
return (stack_overflow_ = true);
}
void AstVisitor::VisitDeclarations(ZoneList<Declaration*>* declarations) { void AstVisitor::VisitDeclarations(ZoneList<Declaration*>* declarations) {
for (int i = 0; i < declarations->length(); i++) { for (int i = 0; i < declarations->length(); i++) {
......
...@@ -2066,29 +2066,23 @@ class AstVisitor BASE_EMBEDDED { ...@@ -2066,29 +2066,23 @@ class AstVisitor BASE_EMBEDDED {
AstVisitor() : stack_overflow_(false) { } AstVisitor() : stack_overflow_(false) { }
virtual ~AstVisitor() { } virtual ~AstVisitor() { }
// Dispatch // Stack overflow check and dynamic dispatch.
void Visit(AstNode* node) { node->Accept(this); } void Visit(AstNode* node) { if (!CheckStackOverflow()) node->Accept(this); }
// Iteration // Iteration left-to-right.
virtual void VisitDeclarations(ZoneList<Declaration*>* declarations); virtual void VisitDeclarations(ZoneList<Declaration*>* declarations);
virtual void VisitStatements(ZoneList<Statement*>* statements); virtual void VisitStatements(ZoneList<Statement*>* statements);
virtual void VisitExpressions(ZoneList<Expression*>* expressions); virtual void VisitExpressions(ZoneList<Expression*>* expressions);
// Stack overflow tracking support. // Stack overflow tracking support.
bool HasStackOverflow() const { return stack_overflow_; } bool HasStackOverflow() const { return stack_overflow_; }
bool CheckStackOverflow() { bool CheckStackOverflow();
if (stack_overflow_) return true;
StackLimitCheck check;
if (!check.HasOverflowed()) return false;
return (stack_overflow_ = true);
}
// If a stack-overflow exception is encountered when visiting a // If a stack-overflow exception is encountered when visiting a
// node, calling SetStackOverflow will make sure that the visitor // node, calling SetStackOverflow will make sure that the visitor
// bails out without visiting more nodes. // bails out without visiting more nodes.
void SetStackOverflow() { stack_overflow_ = true; } void SetStackOverflow() { stack_overflow_ = true; }
// Individual nodes // Individual nodes
#define DEF_VISIT(type) \ #define DEF_VISIT(type) \
virtual void Visit##type(type* node) = 0; virtual void Visit##type(type* node) = 0;
......
...@@ -433,9 +433,7 @@ void FlowGraphBuilder::VisitThisFunction(ThisFunction* expr) { ...@@ -433,9 +433,7 @@ void FlowGraphBuilder::VisitThisFunction(ThisFunction* expr) {
#ifdef DEBUG #ifdef DEBUG
// Print a textual representation of an instruction in a flow graph. Using // Print a textual representation of an instruction in a flow graph.
// the AstVisitor is overkill because there is no recursion here. It is
// however only used for printing in debug mode.
class InstructionPrinter: public AstVisitor { class InstructionPrinter: public AstVisitor {
public: public:
InstructionPrinter() {} InstructionPrinter() {}
...@@ -594,7 +592,7 @@ void InstructionPrinter::VisitVariableProxy(VariableProxy* expr) { ...@@ -594,7 +592,7 @@ void InstructionPrinter::VisitVariableProxy(VariableProxy* expr) {
PrintF("%s", *var->name()->ToCString()); PrintF("%s", *var->name()->ToCString());
} else { } else {
ASSERT(expr->AsProperty() != NULL); ASSERT(expr->AsProperty() != NULL);
VisitProperty(expr->AsProperty()); Visit(expr->AsProperty());
} }
} }
...@@ -726,7 +724,7 @@ int BasicBlock::PrintAsText(int instruction_number) { ...@@ -726,7 +724,7 @@ int BasicBlock::PrintAsText(int instruction_number) {
for (int i = 0; i < instructions_.length(); ++i) { for (int i = 0; i < instructions_.length(); ++i) {
PrintF("\n%d ", instruction_number); PrintF("\n%d ", instruction_number);
instructions_[i]->set_num(instruction_number++); instructions_[i]->set_num(instruction_number++);
printer.Visit(instructions_[i]); instructions_[i]->Accept(&printer);
} }
// If this is the exit, print "exit". If there is a single successor, // If this is the exit, print "exit". If there is a single successor,
......
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