From 789f832e4aeebb927c3882433ab2e30ac343cf96 Mon Sep 17 00:00:00 2001 From: "kmillikin@chromium.org" Date: Tue, 30 Mar 2010 12:25:58 +0000 Subject: [PATCH] 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 --- src/ast.cc | 14 +++++++++----- src/ast.h | 14 ++++---------- src/flow-graph.cc | 8 +++----- 3 files changed, 16 insertions(+), 20 deletions(-) diff --git a/src/ast.cc b/src/ast.cc index 06a86d7..75b2945 100644 --- a/src/ast.cc +++ b/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* declarations) { for (int i = 0; i < declarations->length(); i++) { diff --git a/src/ast.h b/src/ast.h index c6194eb..dfc08ee 100644 --- a/src/ast.h +++ b/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* declarations); virtual void VisitStatements(ZoneList* statements); virtual void VisitExpressions(ZoneList* 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; diff --git a/src/flow-graph.cc b/src/flow-graph.cc index 0b034e2..02a2cd9 100644 --- a/src/flow-graph.cc +++ b/src/flow-graph.cc @@ -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, -- 2.7.4