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:
parent
155a9cdd08
commit
789f832e4a
14
src/ast.cc
14
src/ast.cc
@ -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++) {
|
||||
|
14
src/ast.h
14
src/ast.h
@ -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;
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user