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
This commit is contained in:
kmillikin@chromium.org 2010-03-30 12:25:58 +00:00
parent 155a9cdd08
commit 789f832e4a
3 changed files with 16 additions and 20 deletions

View File

@ -47,11 +47,8 @@ Call Call::sentinel_(NULL, NULL, 0);
// ----------------------------------------------------------------------------
// All the Accept member functions for each syntax tree node type.
#define DECL_ACCEPT(type) \
void type::Accept(AstVisitor* v) { \
if (v->CheckStackOverflow()) return; \
v->Visit##type(this); \
}
#define DECL_ACCEPT(type) \
void type::Accept(AstVisitor* v) { v->Visit##type(this); }
AST_NODE_LIST(DECL_ACCEPT)
#undef DECL_ACCEPT
@ -241,6 +238,13 @@ bool Expression::GuaranteedSmiResult() {
// ----------------------------------------------------------------------------
// 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) {
for (int i = 0; i < declarations->length(); i++) {

View File

@ -2066,29 +2066,23 @@ class AstVisitor BASE_EMBEDDED {
AstVisitor() : stack_overflow_(false) { }
virtual ~AstVisitor() { }
// Dispatch
void Visit(AstNode* node) { node->Accept(this); }
// Stack overflow check and dynamic dispatch.
void Visit(AstNode* node) { if (!CheckStackOverflow()) node->Accept(this); }
// Iteration
// Iteration left-to-right.
virtual void VisitDeclarations(ZoneList<Declaration*>* declarations);
virtual void VisitStatements(ZoneList<Statement*>* statements);
virtual void VisitExpressions(ZoneList<Expression*>* expressions);
// Stack overflow tracking support.
bool HasStackOverflow() const { return stack_overflow_; }
bool CheckStackOverflow() {
if (stack_overflow_) return true;
StackLimitCheck check;
if (!check.HasOverflowed()) return false;
return (stack_overflow_ = true);
}
bool CheckStackOverflow();
// If a stack-overflow exception is encountered when visiting a
// node, calling SetStackOverflow will make sure that the visitor
// bails out without visiting more nodes.
void SetStackOverflow() { stack_overflow_ = true; }
// Individual nodes
#define DEF_VISIT(type) \
virtual void Visit##type(type* node) = 0;

View File

@ -433,9 +433,7 @@ void FlowGraphBuilder::VisitThisFunction(ThisFunction* expr) {
#ifdef DEBUG
// Print a textual representation of an instruction in a flow graph. Using
// the AstVisitor is overkill because there is no recursion here. It is
// however only used for printing in debug mode.
// Print a textual representation of an instruction in a flow graph.
class InstructionPrinter: public AstVisitor {
public:
InstructionPrinter() {}
@ -594,7 +592,7 @@ void InstructionPrinter::VisitVariableProxy(VariableProxy* expr) {
PrintF("%s", *var->name()->ToCString());
} else {
ASSERT(expr->AsProperty() != NULL);
VisitProperty(expr->AsProperty());
Visit(expr->AsProperty());
}
}
@ -726,7 +724,7 @@ int BasicBlock::PrintAsText(int instruction_number) {
for (int i = 0; i < instructions_.length(); ++i) {
PrintF("\n%d ", 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,