[parser] Refactor AstTraversalVisitor
This patch parametrizes AstTraversalVisitor by the actual subclass, in a similar way as AstVisitor is parametrized. This allows a subclass to, e.g., override the Visit method and still use the traversal mechanism. It also allows the subclass to override the specific visiting methods, without them being virtual. This patch also removes AstExpressionVisitor, subsuming its functionality in AstTraversalVisitor. R=adamk@chromium.org, verwaest@chromium.org BUG= LOG=N Review-Url: https://codereview.chromium.org/2169833002 Cr-Commit-Position: refs/heads/master@{#37998}
This commit is contained in:
parent
a189839c53
commit
ad6ea93227
3
BUILD.gn
3
BUILD.gn
@ -838,12 +838,11 @@ v8_source_set("v8_base") {
|
||||
"src/assert-scope.h",
|
||||
"src/ast/ast-expression-rewriter.cc",
|
||||
"src/ast/ast-expression-rewriter.h",
|
||||
"src/ast/ast-expression-visitor.cc",
|
||||
"src/ast/ast-expression-visitor.h",
|
||||
"src/ast/ast-literal-reindexer.cc",
|
||||
"src/ast/ast-literal-reindexer.h",
|
||||
"src/ast/ast-numbering.cc",
|
||||
"src/ast/ast-numbering.h",
|
||||
"src/ast/ast-traversal-visitor.h",
|
||||
"src/ast/ast-type-bounds.h",
|
||||
"src/ast/ast-value-factory.cc",
|
||||
"src/ast/ast-value-factory.h",
|
||||
|
@ -1,167 +0,0 @@
|
||||
// Copyright 2015 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "src/v8.h"
|
||||
|
||||
#include "src/ast/ast-expression-visitor.h"
|
||||
|
||||
#include "src/ast/ast.h"
|
||||
#include "src/ast/scopes.h"
|
||||
#include "src/codegen.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
AstExpressionVisitor::AstExpressionVisitor(Isolate* isolate, Expression* root)
|
||||
: AstTraversalVisitor(isolate), root_(root) {}
|
||||
|
||||
AstExpressionVisitor::AstExpressionVisitor(uintptr_t stack_limit,
|
||||
Expression* root)
|
||||
: AstTraversalVisitor(stack_limit), root_(root) {}
|
||||
|
||||
void AstExpressionVisitor::Run() { Visit(root_); }
|
||||
|
||||
void AstExpressionVisitor::VisitFunctionLiteral(FunctionLiteral* expr) {
|
||||
VisitExpression(expr);
|
||||
AstTraversalVisitor::VisitFunctionLiteral(expr);
|
||||
}
|
||||
|
||||
void AstExpressionVisitor::VisitNativeFunctionLiteral(
|
||||
NativeFunctionLiteral* expr) {
|
||||
AstTraversalVisitor::VisitNativeFunctionLiteral(expr);
|
||||
}
|
||||
|
||||
void AstExpressionVisitor::VisitDoExpression(DoExpression* expr) {
|
||||
VisitExpression(expr);
|
||||
AstTraversalVisitor::VisitDoExpression(expr);
|
||||
}
|
||||
|
||||
void AstExpressionVisitor::VisitConditional(Conditional* expr) {
|
||||
VisitExpression(expr);
|
||||
AstTraversalVisitor::VisitConditional(expr);
|
||||
}
|
||||
|
||||
void AstExpressionVisitor::VisitVariableProxy(VariableProxy* expr) {
|
||||
VisitExpression(expr);
|
||||
AstTraversalVisitor::VisitVariableProxy(expr);
|
||||
}
|
||||
|
||||
void AstExpressionVisitor::VisitLiteral(Literal* expr) {
|
||||
VisitExpression(expr);
|
||||
AstTraversalVisitor::VisitLiteral(expr);
|
||||
}
|
||||
|
||||
void AstExpressionVisitor::VisitRegExpLiteral(RegExpLiteral* expr) {
|
||||
VisitExpression(expr);
|
||||
AstTraversalVisitor::VisitRegExpLiteral(expr);
|
||||
}
|
||||
|
||||
void AstExpressionVisitor::VisitObjectLiteral(ObjectLiteral* expr) {
|
||||
VisitExpression(expr);
|
||||
AstTraversalVisitor::VisitObjectLiteral(expr);
|
||||
}
|
||||
|
||||
void AstExpressionVisitor::VisitArrayLiteral(ArrayLiteral* expr) {
|
||||
VisitExpression(expr);
|
||||
AstTraversalVisitor::VisitArrayLiteral(expr);
|
||||
}
|
||||
|
||||
void AstExpressionVisitor::VisitAssignment(Assignment* expr) {
|
||||
VisitExpression(expr);
|
||||
AstTraversalVisitor::VisitAssignment(expr);
|
||||
}
|
||||
|
||||
void AstExpressionVisitor::VisitYield(Yield* expr) {
|
||||
VisitExpression(expr);
|
||||
AstTraversalVisitor::VisitYield(expr);
|
||||
}
|
||||
|
||||
void AstExpressionVisitor::VisitThrow(Throw* expr) {
|
||||
VisitExpression(expr);
|
||||
AstTraversalVisitor::VisitThrow(expr);
|
||||
}
|
||||
|
||||
void AstExpressionVisitor::VisitProperty(Property* expr) {
|
||||
VisitExpression(expr);
|
||||
AstTraversalVisitor::VisitProperty(expr);
|
||||
}
|
||||
|
||||
void AstExpressionVisitor::VisitCall(Call* expr) {
|
||||
VisitExpression(expr);
|
||||
AstTraversalVisitor::VisitCall(expr);
|
||||
}
|
||||
|
||||
void AstExpressionVisitor::VisitCallNew(CallNew* expr) {
|
||||
VisitExpression(expr);
|
||||
AstTraversalVisitor::VisitCallNew(expr);
|
||||
}
|
||||
|
||||
void AstExpressionVisitor::VisitCallRuntime(CallRuntime* expr) {
|
||||
VisitExpression(expr);
|
||||
AstTraversalVisitor::VisitCallRuntime(expr);
|
||||
}
|
||||
|
||||
void AstExpressionVisitor::VisitUnaryOperation(UnaryOperation* expr) {
|
||||
VisitExpression(expr);
|
||||
AstTraversalVisitor::VisitUnaryOperation(expr);
|
||||
}
|
||||
|
||||
void AstExpressionVisitor::VisitCountOperation(CountOperation* expr) {
|
||||
VisitExpression(expr);
|
||||
AstTraversalVisitor::VisitCountOperation(expr);
|
||||
}
|
||||
|
||||
void AstExpressionVisitor::VisitBinaryOperation(BinaryOperation* expr) {
|
||||
VisitExpression(expr);
|
||||
AstTraversalVisitor::VisitBinaryOperation(expr);
|
||||
}
|
||||
|
||||
void AstExpressionVisitor::VisitCompareOperation(CompareOperation* expr) {
|
||||
VisitExpression(expr);
|
||||
AstTraversalVisitor::VisitCompareOperation(expr);
|
||||
}
|
||||
|
||||
void AstExpressionVisitor::VisitThisFunction(ThisFunction* expr) {
|
||||
VisitExpression(expr);
|
||||
AstTraversalVisitor::VisitThisFunction(expr);
|
||||
}
|
||||
|
||||
void AstExpressionVisitor::VisitClassLiteral(ClassLiteral* expr) {
|
||||
VisitExpression(expr);
|
||||
AstTraversalVisitor::VisitClassLiteral(expr);
|
||||
}
|
||||
|
||||
void AstExpressionVisitor::VisitSpread(Spread* expr) {
|
||||
VisitExpression(expr);
|
||||
AstTraversalVisitor::VisitSpread(expr);
|
||||
}
|
||||
|
||||
void AstExpressionVisitor::VisitSuperPropertyReference(
|
||||
SuperPropertyReference* expr) {
|
||||
VisitExpression(expr);
|
||||
AstTraversalVisitor::VisitSuperPropertyReference(expr);
|
||||
}
|
||||
|
||||
void AstExpressionVisitor::VisitSuperCallReference(SuperCallReference* expr) {
|
||||
VisitExpression(expr);
|
||||
AstTraversalVisitor::VisitSuperCallReference(expr);
|
||||
}
|
||||
|
||||
void AstExpressionVisitor::VisitCaseClause(CaseClause* expr) {
|
||||
AstTraversalVisitor::VisitCaseClause(expr);
|
||||
}
|
||||
|
||||
void AstExpressionVisitor::VisitEmptyParentheses(EmptyParentheses* expr) {
|
||||
AstTraversalVisitor::VisitEmptyParentheses(expr);
|
||||
}
|
||||
|
||||
void AstExpressionVisitor::VisitRewritableExpression(
|
||||
RewritableExpression* expr) {
|
||||
VisitExpression(expr);
|
||||
AstTraversalVisitor::VisitRewritableExpression(expr);
|
||||
}
|
||||
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
@ -1,41 +0,0 @@
|
||||
// Copyright 2015 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef V8_AST_AST_EXPRESSION_VISITOR_H_
|
||||
#define V8_AST_AST_EXPRESSION_VISITOR_H_
|
||||
|
||||
#include "src/allocation.h"
|
||||
#include "src/ast/ast.h"
|
||||
#include "src/ast/scopes.h"
|
||||
#include "src/type-info.h"
|
||||
#include "src/zone.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
// A Visitor over a CompilationInfo's AST that invokes
|
||||
// VisitExpression on each expression node.
|
||||
|
||||
class AstExpressionVisitor : public AstTraversalVisitor {
|
||||
public:
|
||||
AstExpressionVisitor(Isolate* isolate, Expression* root);
|
||||
AstExpressionVisitor(uintptr_t stack_limit, Expression* root);
|
||||
void Run();
|
||||
|
||||
protected:
|
||||
virtual void VisitExpression(Expression* expression) = 0;
|
||||
|
||||
private:
|
||||
#define DECLARE_VISIT(type) void Visit##type(type* node) override;
|
||||
EXPRESSION_NODE_LIST(DECLARE_VISIT)
|
||||
#undef DECLARE_VISIT
|
||||
|
||||
Expression* root_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AstExpressionVisitor);
|
||||
};
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#endif // V8_AST_AST_EXPRESSION_VISITOR_H_
|
504
src/ast/ast-traversal-visitor.h
Normal file
504
src/ast/ast-traversal-visitor.h
Normal file
@ -0,0 +1,504 @@
|
||||
// Copyright 2016 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef V8_AST_AST_TRAVERSAL_VISITOR_H_
|
||||
#define V8_AST_AST_TRAVERSAL_VISITOR_H_
|
||||
|
||||
#include "src/ast/ast.h"
|
||||
#include "src/ast/scopes.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Traversal visitor
|
||||
// - fully traverses the entire AST.
|
||||
//
|
||||
// Sub-class should parametrize AstTraversalVisitor with itself, e.g.:
|
||||
// class SpecificVisitor : public AstTraversalVisitor<SpecificVisitor> { ... }
|
||||
//
|
||||
// It invokes VisitNode on each AST node, before proceeding with its subtrees.
|
||||
// It invokes VisitExpression (after VisitNode) on each AST node that is an
|
||||
// expression, before proceeding with its subtrees.
|
||||
// It proceeds with the subtrees only if these two methods return true.
|
||||
// Sub-classes may override VisitNode and VisitExpressions, whose implementation
|
||||
// is dummy here. Or they may override the specific Visit* methods.
|
||||
|
||||
template <class Subclass>
|
||||
class AstTraversalVisitor : public AstVisitor<Subclass> {
|
||||
public:
|
||||
explicit AstTraversalVisitor(Isolate* isolate, AstNode* root = nullptr);
|
||||
explicit AstTraversalVisitor(uintptr_t stack_limit, AstNode* root = nullptr);
|
||||
|
||||
void Run() {
|
||||
DCHECK_NOT_NULL(root_);
|
||||
Visit(root_);
|
||||
}
|
||||
|
||||
bool VisitNode(AstNode* node) { return true; }
|
||||
bool VisitExpression(Expression* node) { return true; }
|
||||
|
||||
// Iteration left-to-right.
|
||||
void VisitDeclarations(ZoneList<Declaration*>* declarations);
|
||||
void VisitStatements(ZoneList<Statement*>* statements);
|
||||
|
||||
// Individual nodes
|
||||
#define DECLARE_VISIT(type) void Visit##type(type* node);
|
||||
AST_NODE_LIST(DECLARE_VISIT)
|
||||
#undef DECLARE_VISIT
|
||||
|
||||
protected:
|
||||
int depth() const { return depth_; }
|
||||
|
||||
private:
|
||||
DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
|
||||
|
||||
AstNode* root_;
|
||||
int depth_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AstTraversalVisitor);
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Implementation of AstTraversalVisitor
|
||||
|
||||
#define PROCESS_NODE(node) do { \
|
||||
if (!(this->impl()->VisitNode(node))) return; \
|
||||
} while (false)
|
||||
|
||||
#define PROCESS_EXPRESSION(node) do { \
|
||||
PROCESS_NODE(node); \
|
||||
if (!(this->impl()->VisitExpression(node))) return; \
|
||||
} while (false)
|
||||
|
||||
#define RECURSE(call) \
|
||||
do { \
|
||||
DCHECK(!HasStackOverflow()); \
|
||||
this->impl()->call; \
|
||||
if (HasStackOverflow()) return; \
|
||||
} while (false)
|
||||
|
||||
#define RECURSE_EXPRESSION(call) \
|
||||
do { \
|
||||
DCHECK(!HasStackOverflow()); \
|
||||
++depth_; \
|
||||
this->impl()->call; \
|
||||
--depth_; \
|
||||
if (HasStackOverflow()) return; \
|
||||
} while (false)
|
||||
|
||||
template <class Subclass>
|
||||
AstTraversalVisitor<Subclass>::AstTraversalVisitor(Isolate* isolate,
|
||||
AstNode* root)
|
||||
: root_(root), depth_(0) {
|
||||
InitializeAstVisitor(isolate);
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
AstTraversalVisitor<Subclass>::AstTraversalVisitor(uintptr_t stack_limit,
|
||||
AstNode* root)
|
||||
: root_(root), depth_(0) {
|
||||
InitializeAstVisitor(stack_limit);
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitDeclarations(
|
||||
ZoneList<Declaration*>* decls) {
|
||||
for (int i = 0; i < decls->length(); ++i) {
|
||||
Declaration* decl = decls->at(i);
|
||||
RECURSE(Visit(decl));
|
||||
}
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitStatements(
|
||||
ZoneList<Statement*>* stmts) {
|
||||
for (int i = 0; i < stmts->length(); ++i) {
|
||||
Statement* stmt = stmts->at(i);
|
||||
RECURSE(Visit(stmt));
|
||||
if (stmt->IsJump()) break;
|
||||
}
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitVariableDeclaration(
|
||||
VariableDeclaration* decl) {
|
||||
PROCESS_NODE(decl);
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitFunctionDeclaration(
|
||||
FunctionDeclaration* decl) {
|
||||
PROCESS_NODE(decl);
|
||||
RECURSE(Visit(decl->fun()));
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitBlock(Block* stmt) {
|
||||
PROCESS_NODE(stmt);
|
||||
RECURSE(VisitStatements(stmt->statements()));
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitExpressionStatement(
|
||||
ExpressionStatement* stmt) {
|
||||
PROCESS_NODE(stmt);
|
||||
RECURSE(Visit(stmt->expression()));
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitEmptyStatement(EmptyStatement* stmt) {}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitSloppyBlockFunctionStatement(
|
||||
SloppyBlockFunctionStatement* stmt) {
|
||||
PROCESS_NODE(stmt);
|
||||
RECURSE(Visit(stmt->statement()));
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitIfStatement(IfStatement* stmt) {
|
||||
PROCESS_NODE(stmt);
|
||||
RECURSE(Visit(stmt->condition()));
|
||||
RECURSE(Visit(stmt->then_statement()));
|
||||
RECURSE(Visit(stmt->else_statement()));
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitContinueStatement(
|
||||
ContinueStatement* stmt) {
|
||||
PROCESS_NODE(stmt);
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitBreakStatement(BreakStatement* stmt) {
|
||||
PROCESS_NODE(stmt);
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitReturnStatement(
|
||||
ReturnStatement* stmt) {
|
||||
PROCESS_NODE(stmt);
|
||||
RECURSE(Visit(stmt->expression()));
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitWithStatement(WithStatement* stmt) {
|
||||
PROCESS_NODE(stmt);
|
||||
RECURSE(Visit(stmt->expression()));
|
||||
RECURSE(Visit(stmt->statement()));
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitSwitchStatement(
|
||||
SwitchStatement* stmt) {
|
||||
PROCESS_NODE(stmt);
|
||||
RECURSE(Visit(stmt->tag()));
|
||||
|
||||
ZoneList<CaseClause*>* clauses = stmt->cases();
|
||||
for (int i = 0; i < clauses->length(); ++i) {
|
||||
CaseClause* clause = clauses->at(i);
|
||||
if (!clause->is_default()) {
|
||||
Expression* label = clause->label();
|
||||
RECURSE(Visit(label));
|
||||
}
|
||||
ZoneList<Statement*>* stmts = clause->statements();
|
||||
RECURSE(VisitStatements(stmts));
|
||||
}
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitCaseClause(CaseClause* clause) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitDoWhileStatement(
|
||||
DoWhileStatement* stmt) {
|
||||
PROCESS_NODE(stmt);
|
||||
RECURSE(Visit(stmt->body()));
|
||||
RECURSE(Visit(stmt->cond()));
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitWhileStatement(WhileStatement* stmt) {
|
||||
PROCESS_NODE(stmt);
|
||||
RECURSE(Visit(stmt->cond()));
|
||||
RECURSE(Visit(stmt->body()));
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitForStatement(ForStatement* stmt) {
|
||||
PROCESS_NODE(stmt);
|
||||
if (stmt->init() != NULL) {
|
||||
RECURSE(Visit(stmt->init()));
|
||||
}
|
||||
if (stmt->cond() != NULL) {
|
||||
RECURSE(Visit(stmt->cond()));
|
||||
}
|
||||
if (stmt->next() != NULL) {
|
||||
RECURSE(Visit(stmt->next()));
|
||||
}
|
||||
RECURSE(Visit(stmt->body()));
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitForInStatement(ForInStatement* stmt) {
|
||||
PROCESS_NODE(stmt);
|
||||
RECURSE(Visit(stmt->enumerable()));
|
||||
RECURSE(Visit(stmt->body()));
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitForOfStatement(ForOfStatement* stmt) {
|
||||
PROCESS_NODE(stmt);
|
||||
RECURSE(Visit(stmt->assign_iterator()));
|
||||
RECURSE(Visit(stmt->next_result()));
|
||||
RECURSE(Visit(stmt->result_done()));
|
||||
RECURSE(Visit(stmt->assign_each()));
|
||||
RECURSE(Visit(stmt->body()));
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitTryCatchStatement(
|
||||
TryCatchStatement* stmt) {
|
||||
PROCESS_NODE(stmt);
|
||||
RECURSE(Visit(stmt->try_block()));
|
||||
RECURSE(Visit(stmt->catch_block()));
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitTryFinallyStatement(
|
||||
TryFinallyStatement* stmt) {
|
||||
PROCESS_NODE(stmt);
|
||||
RECURSE(Visit(stmt->try_block()));
|
||||
RECURSE(Visit(stmt->finally_block()));
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitDebuggerStatement(
|
||||
DebuggerStatement* stmt) {
|
||||
PROCESS_NODE(stmt);
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitFunctionLiteral(
|
||||
FunctionLiteral* expr) {
|
||||
PROCESS_EXPRESSION(expr);
|
||||
Scope* scope = expr->scope();
|
||||
RECURSE_EXPRESSION(VisitDeclarations(scope->declarations()));
|
||||
RECURSE_EXPRESSION(VisitStatements(expr->body()));
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitNativeFunctionLiteral(
|
||||
NativeFunctionLiteral* expr) {
|
||||
PROCESS_EXPRESSION(expr);
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitDoExpression(DoExpression* expr) {
|
||||
PROCESS_EXPRESSION(expr);
|
||||
RECURSE(VisitBlock(expr->block()));
|
||||
RECURSE(VisitVariableProxy(expr->result()));
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitConditional(Conditional* expr) {
|
||||
PROCESS_EXPRESSION(expr);
|
||||
RECURSE_EXPRESSION(Visit(expr->condition()));
|
||||
RECURSE_EXPRESSION(Visit(expr->then_expression()));
|
||||
RECURSE_EXPRESSION(Visit(expr->else_expression()));
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitVariableProxy(VariableProxy* expr) {
|
||||
PROCESS_EXPRESSION(expr);
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitLiteral(Literal* expr) {
|
||||
PROCESS_EXPRESSION(expr);
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitRegExpLiteral(RegExpLiteral* expr) {
|
||||
PROCESS_EXPRESSION(expr);
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitObjectLiteral(ObjectLiteral* expr) {
|
||||
PROCESS_EXPRESSION(expr);
|
||||
ZoneList<ObjectLiteralProperty*>* props = expr->properties();
|
||||
for (int i = 0; i < props->length(); ++i) {
|
||||
ObjectLiteralProperty* prop = props->at(i);
|
||||
RECURSE_EXPRESSION(Visit(prop->key()));
|
||||
RECURSE_EXPRESSION(Visit(prop->value()));
|
||||
}
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitArrayLiteral(ArrayLiteral* expr) {
|
||||
PROCESS_EXPRESSION(expr);
|
||||
ZoneList<Expression*>* values = expr->values();
|
||||
for (int i = 0; i < values->length(); ++i) {
|
||||
Expression* value = values->at(i);
|
||||
RECURSE_EXPRESSION(Visit(value));
|
||||
}
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitAssignment(Assignment* expr) {
|
||||
PROCESS_EXPRESSION(expr);
|
||||
RECURSE_EXPRESSION(Visit(expr->target()));
|
||||
RECURSE_EXPRESSION(Visit(expr->value()));
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitYield(Yield* expr) {
|
||||
PROCESS_EXPRESSION(expr);
|
||||
RECURSE_EXPRESSION(Visit(expr->generator_object()));
|
||||
RECURSE_EXPRESSION(Visit(expr->expression()));
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitThrow(Throw* expr) {
|
||||
PROCESS_EXPRESSION(expr);
|
||||
RECURSE_EXPRESSION(Visit(expr->exception()));
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitProperty(Property* expr) {
|
||||
PROCESS_EXPRESSION(expr);
|
||||
RECURSE_EXPRESSION(Visit(expr->obj()));
|
||||
RECURSE_EXPRESSION(Visit(expr->key()));
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitCall(Call* expr) {
|
||||
PROCESS_EXPRESSION(expr);
|
||||
RECURSE_EXPRESSION(Visit(expr->expression()));
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
for (int i = 0; i < args->length(); ++i) {
|
||||
Expression* arg = args->at(i);
|
||||
RECURSE_EXPRESSION(Visit(arg));
|
||||
}
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitCallNew(CallNew* expr) {
|
||||
PROCESS_EXPRESSION(expr);
|
||||
RECURSE_EXPRESSION(Visit(expr->expression()));
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
for (int i = 0; i < args->length(); ++i) {
|
||||
Expression* arg = args->at(i);
|
||||
RECURSE_EXPRESSION(Visit(arg));
|
||||
}
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitCallRuntime(CallRuntime* expr) {
|
||||
PROCESS_EXPRESSION(expr);
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
for (int i = 0; i < args->length(); ++i) {
|
||||
Expression* arg = args->at(i);
|
||||
RECURSE_EXPRESSION(Visit(arg));
|
||||
}
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitUnaryOperation(UnaryOperation* expr) {
|
||||
PROCESS_EXPRESSION(expr);
|
||||
RECURSE_EXPRESSION(Visit(expr->expression()));
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitCountOperation(CountOperation* expr) {
|
||||
PROCESS_EXPRESSION(expr);
|
||||
RECURSE_EXPRESSION(Visit(expr->expression()));
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitBinaryOperation(
|
||||
BinaryOperation* expr) {
|
||||
PROCESS_EXPRESSION(expr);
|
||||
RECURSE_EXPRESSION(Visit(expr->left()));
|
||||
RECURSE_EXPRESSION(Visit(expr->right()));
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitCompareOperation(
|
||||
CompareOperation* expr) {
|
||||
PROCESS_EXPRESSION(expr);
|
||||
RECURSE_EXPRESSION(Visit(expr->left()));
|
||||
RECURSE_EXPRESSION(Visit(expr->right()));
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitThisFunction(ThisFunction* expr) {
|
||||
PROCESS_EXPRESSION(expr);
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitClassLiteral(ClassLiteral* expr) {
|
||||
PROCESS_EXPRESSION(expr);
|
||||
if (expr->extends() != nullptr) {
|
||||
RECURSE_EXPRESSION(Visit(expr->extends()));
|
||||
}
|
||||
RECURSE_EXPRESSION(Visit(expr->constructor()));
|
||||
ZoneList<ObjectLiteralProperty*>* props = expr->properties();
|
||||
for (int i = 0; i < props->length(); ++i) {
|
||||
ObjectLiteralProperty* prop = props->at(i);
|
||||
if (!prop->key()->IsLiteral()) {
|
||||
RECURSE_EXPRESSION(Visit(prop->key()));
|
||||
}
|
||||
RECURSE_EXPRESSION(Visit(prop->value()));
|
||||
}
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitSpread(Spread* expr) {
|
||||
PROCESS_EXPRESSION(expr);
|
||||
RECURSE_EXPRESSION(Visit(expr->expression()));
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitEmptyParentheses(
|
||||
EmptyParentheses* expr) {
|
||||
PROCESS_EXPRESSION(expr);
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitSuperPropertyReference(
|
||||
SuperPropertyReference* expr) {
|
||||
PROCESS_EXPRESSION(expr);
|
||||
RECURSE_EXPRESSION(VisitVariableProxy(expr->this_var()));
|
||||
RECURSE_EXPRESSION(Visit(expr->home_object()));
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitSuperCallReference(
|
||||
SuperCallReference* expr) {
|
||||
PROCESS_EXPRESSION(expr);
|
||||
RECURSE_EXPRESSION(VisitVariableProxy(expr->this_var()));
|
||||
RECURSE_EXPRESSION(VisitVariableProxy(expr->new_target_var()));
|
||||
RECURSE_EXPRESSION(VisitVariableProxy(expr->this_function_var()));
|
||||
}
|
||||
|
||||
template <class Subclass>
|
||||
void AstTraversalVisitor<Subclass>::VisitRewritableExpression(
|
||||
RewritableExpression* expr) {
|
||||
PROCESS_EXPRESSION(expr);
|
||||
RECURSE(Visit(expr->expression()));
|
||||
}
|
||||
|
||||
#undef PROCESS_NODE
|
||||
#undef PROCESS_EXPRESSION
|
||||
#undef RECURSE_EXPRESSION
|
||||
#undef RECURSE
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#endif // V8_AST_AST_TRAVERSAL_VISITOR_H_
|
299
src/ast/ast.cc
299
src/ast/ast.cc
@ -923,305 +923,6 @@ Call::CallType Call::GetCallType(Isolate* isolate) const {
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Implementation of AstTraversalVisitor
|
||||
|
||||
#define RECURSE(call) \
|
||||
do { \
|
||||
DCHECK(!HasStackOverflow()); \
|
||||
call; \
|
||||
if (HasStackOverflow()) return; \
|
||||
} while (false)
|
||||
|
||||
#define RECURSE_EXPRESSION(call) \
|
||||
do { \
|
||||
DCHECK(!HasStackOverflow()); \
|
||||
++depth_; \
|
||||
call; \
|
||||
--depth_; \
|
||||
if (HasStackOverflow()) return; \
|
||||
} while (false)
|
||||
|
||||
AstTraversalVisitor::AstTraversalVisitor(Isolate* isolate) : depth_(0) {
|
||||
InitializeAstVisitor(isolate);
|
||||
}
|
||||
|
||||
AstTraversalVisitor::AstTraversalVisitor(uintptr_t stack_limit) : depth_(0) {
|
||||
InitializeAstVisitor(stack_limit);
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitDeclarations(ZoneList<Declaration*>* decls) {
|
||||
for (int i = 0; i < decls->length(); ++i) {
|
||||
Declaration* decl = decls->at(i);
|
||||
RECURSE(Visit(decl));
|
||||
}
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitStatements(ZoneList<Statement*>* stmts) {
|
||||
for (int i = 0; i < stmts->length(); ++i) {
|
||||
Statement* stmt = stmts->at(i);
|
||||
RECURSE(Visit(stmt));
|
||||
if (stmt->IsJump()) break;
|
||||
}
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitVariableDeclaration(VariableDeclaration* decl) {}
|
||||
|
||||
void AstTraversalVisitor::VisitFunctionDeclaration(FunctionDeclaration* decl) {
|
||||
RECURSE(Visit(decl->fun()));
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitBlock(Block* stmt) {
|
||||
RECURSE(VisitStatements(stmt->statements()));
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitExpressionStatement(ExpressionStatement* stmt) {
|
||||
RECURSE(Visit(stmt->expression()));
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitEmptyStatement(EmptyStatement* stmt) {}
|
||||
|
||||
void AstTraversalVisitor::VisitSloppyBlockFunctionStatement(
|
||||
SloppyBlockFunctionStatement* stmt) {
|
||||
RECURSE(Visit(stmt->statement()));
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitIfStatement(IfStatement* stmt) {
|
||||
RECURSE(Visit(stmt->condition()));
|
||||
RECURSE(Visit(stmt->then_statement()));
|
||||
RECURSE(Visit(stmt->else_statement()));
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitContinueStatement(ContinueStatement* stmt) {}
|
||||
|
||||
void AstTraversalVisitor::VisitBreakStatement(BreakStatement* stmt) {}
|
||||
|
||||
void AstTraversalVisitor::VisitReturnStatement(ReturnStatement* stmt) {
|
||||
RECURSE(Visit(stmt->expression()));
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitWithStatement(WithStatement* stmt) {
|
||||
RECURSE(stmt->expression());
|
||||
RECURSE(stmt->statement());
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitSwitchStatement(SwitchStatement* stmt) {
|
||||
RECURSE(Visit(stmt->tag()));
|
||||
|
||||
ZoneList<CaseClause*>* clauses = stmt->cases();
|
||||
|
||||
for (int i = 0; i < clauses->length(); ++i) {
|
||||
CaseClause* clause = clauses->at(i);
|
||||
if (!clause->is_default()) {
|
||||
Expression* label = clause->label();
|
||||
RECURSE(Visit(label));
|
||||
}
|
||||
ZoneList<Statement*>* stmts = clause->statements();
|
||||
RECURSE(VisitStatements(stmts));
|
||||
}
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitCaseClause(CaseClause* clause) { UNREACHABLE(); }
|
||||
|
||||
void AstTraversalVisitor::VisitDoWhileStatement(DoWhileStatement* stmt) {
|
||||
RECURSE(Visit(stmt->body()));
|
||||
RECURSE(Visit(stmt->cond()));
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitWhileStatement(WhileStatement* stmt) {
|
||||
RECURSE(Visit(stmt->cond()));
|
||||
RECURSE(Visit(stmt->body()));
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitForStatement(ForStatement* stmt) {
|
||||
if (stmt->init() != NULL) {
|
||||
RECURSE(Visit(stmt->init()));
|
||||
}
|
||||
if (stmt->cond() != NULL) {
|
||||
RECURSE(Visit(stmt->cond()));
|
||||
}
|
||||
if (stmt->next() != NULL) {
|
||||
RECURSE(Visit(stmt->next()));
|
||||
}
|
||||
RECURSE(Visit(stmt->body()));
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitForInStatement(ForInStatement* stmt) {
|
||||
RECURSE(Visit(stmt->enumerable()));
|
||||
RECURSE(Visit(stmt->body()));
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitForOfStatement(ForOfStatement* stmt) {
|
||||
RECURSE(Visit(stmt->assign_iterator()));
|
||||
RECURSE(Visit(stmt->next_result()));
|
||||
RECURSE(Visit(stmt->result_done()));
|
||||
RECURSE(Visit(stmt->assign_each()));
|
||||
RECURSE(Visit(stmt->body()));
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitTryCatchStatement(TryCatchStatement* stmt) {
|
||||
RECURSE(Visit(stmt->try_block()));
|
||||
RECURSE(Visit(stmt->catch_block()));
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
|
||||
RECURSE(Visit(stmt->try_block()));
|
||||
RECURSE(Visit(stmt->finally_block()));
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitDebuggerStatement(DebuggerStatement* stmt) {}
|
||||
|
||||
void AstTraversalVisitor::VisitFunctionLiteral(FunctionLiteral* expr) {
|
||||
Scope* scope = expr->scope();
|
||||
RECURSE_EXPRESSION(VisitDeclarations(scope->declarations()));
|
||||
RECURSE_EXPRESSION(VisitStatements(expr->body()));
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitNativeFunctionLiteral(
|
||||
NativeFunctionLiteral* expr) {}
|
||||
|
||||
void AstTraversalVisitor::VisitDoExpression(DoExpression* expr) {
|
||||
RECURSE(VisitBlock(expr->block()));
|
||||
RECURSE(VisitVariableProxy(expr->result()));
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitConditional(Conditional* expr) {
|
||||
RECURSE_EXPRESSION(Visit(expr->condition()));
|
||||
RECURSE_EXPRESSION(Visit(expr->then_expression()));
|
||||
RECURSE_EXPRESSION(Visit(expr->else_expression()));
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitVariableProxy(VariableProxy* expr) {}
|
||||
|
||||
void AstTraversalVisitor::VisitLiteral(Literal* expr) {}
|
||||
|
||||
void AstTraversalVisitor::VisitRegExpLiteral(RegExpLiteral* expr) {}
|
||||
|
||||
void AstTraversalVisitor::VisitObjectLiteral(ObjectLiteral* expr) {
|
||||
ZoneList<ObjectLiteralProperty*>* props = expr->properties();
|
||||
for (int i = 0; i < props->length(); ++i) {
|
||||
ObjectLiteralProperty* prop = props->at(i);
|
||||
if (!prop->key()->IsLiteral()) {
|
||||
RECURSE_EXPRESSION(Visit(prop->key()));
|
||||
}
|
||||
RECURSE_EXPRESSION(Visit(prop->value()));
|
||||
}
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitArrayLiteral(ArrayLiteral* expr) {
|
||||
ZoneList<Expression*>* values = expr->values();
|
||||
for (int i = 0; i < values->length(); ++i) {
|
||||
Expression* value = values->at(i);
|
||||
RECURSE_EXPRESSION(Visit(value));
|
||||
}
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitAssignment(Assignment* expr) {
|
||||
RECURSE_EXPRESSION(Visit(expr->target()));
|
||||
RECURSE_EXPRESSION(Visit(expr->value()));
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitYield(Yield* expr) {
|
||||
RECURSE_EXPRESSION(Visit(expr->generator_object()));
|
||||
RECURSE_EXPRESSION(Visit(expr->expression()));
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitThrow(Throw* expr) {
|
||||
RECURSE_EXPRESSION(Visit(expr->exception()));
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitProperty(Property* expr) {
|
||||
RECURSE_EXPRESSION(Visit(expr->obj()));
|
||||
RECURSE_EXPRESSION(Visit(expr->key()));
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitCall(Call* expr) {
|
||||
RECURSE_EXPRESSION(Visit(expr->expression()));
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
for (int i = 0; i < args->length(); ++i) {
|
||||
Expression* arg = args->at(i);
|
||||
RECURSE_EXPRESSION(Visit(arg));
|
||||
}
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitCallNew(CallNew* expr) {
|
||||
RECURSE_EXPRESSION(Visit(expr->expression()));
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
for (int i = 0; i < args->length(); ++i) {
|
||||
Expression* arg = args->at(i);
|
||||
RECURSE_EXPRESSION(Visit(arg));
|
||||
}
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitCallRuntime(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
for (int i = 0; i < args->length(); ++i) {
|
||||
Expression* arg = args->at(i);
|
||||
RECURSE_EXPRESSION(Visit(arg));
|
||||
}
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitUnaryOperation(UnaryOperation* expr) {
|
||||
RECURSE_EXPRESSION(Visit(expr->expression()));
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitCountOperation(CountOperation* expr) {
|
||||
RECURSE_EXPRESSION(Visit(expr->expression()));
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitBinaryOperation(BinaryOperation* expr) {
|
||||
RECURSE_EXPRESSION(Visit(expr->left()));
|
||||
RECURSE_EXPRESSION(Visit(expr->right()));
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitCompareOperation(CompareOperation* expr) {
|
||||
RECURSE_EXPRESSION(Visit(expr->left()));
|
||||
RECURSE_EXPRESSION(Visit(expr->right()));
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitThisFunction(ThisFunction* expr) {}
|
||||
|
||||
void AstTraversalVisitor::VisitClassLiteral(ClassLiteral* expr) {
|
||||
if (expr->extends() != nullptr) {
|
||||
RECURSE_EXPRESSION(Visit(expr->extends()));
|
||||
}
|
||||
RECURSE_EXPRESSION(Visit(expr->constructor()));
|
||||
ZoneList<ObjectLiteralProperty*>* props = expr->properties();
|
||||
for (int i = 0; i < props->length(); ++i) {
|
||||
ObjectLiteralProperty* prop = props->at(i);
|
||||
if (!prop->key()->IsLiteral()) {
|
||||
RECURSE_EXPRESSION(Visit(prop->key()));
|
||||
}
|
||||
RECURSE_EXPRESSION(Visit(prop->value()));
|
||||
}
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitSpread(Spread* expr) {
|
||||
RECURSE_EXPRESSION(Visit(expr->expression()));
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitEmptyParentheses(EmptyParentheses* expr) {}
|
||||
|
||||
void AstTraversalVisitor::VisitSuperPropertyReference(
|
||||
SuperPropertyReference* expr) {
|
||||
RECURSE_EXPRESSION(VisitVariableProxy(expr->this_var()));
|
||||
RECURSE_EXPRESSION(Visit(expr->home_object()));
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitSuperCallReference(SuperCallReference* expr) {
|
||||
RECURSE_EXPRESSION(VisitVariableProxy(expr->this_var()));
|
||||
RECURSE_EXPRESSION(VisitVariableProxy(expr->new_target_var()));
|
||||
RECURSE_EXPRESSION(VisitVariableProxy(expr->this_function_var()));
|
||||
}
|
||||
|
||||
void AstTraversalVisitor::VisitRewritableExpression(
|
||||
RewritableExpression* expr) {
|
||||
RECURSE(Visit(expr->expression()));
|
||||
}
|
||||
|
||||
#undef RECURSE_EXPRESSION
|
||||
#undef RECURSE
|
||||
|
||||
CaseClause::CaseClause(Zone* zone, Expression* label,
|
||||
ZoneList<Statement*>* statements, int pos)
|
||||
: Expression(zone, pos, kCaseClause),
|
||||
|
@ -2893,7 +2893,7 @@ class EmptyParentheses final : public Expression {
|
||||
template <class Subclass>
|
||||
class AstVisitor BASE_EMBEDDED {
|
||||
public:
|
||||
void Visit(AstNode* node) { This()->Visit(node); }
|
||||
void Visit(AstNode* node) { impl()->Visit(node); }
|
||||
|
||||
void VisitDeclarations(ZoneList<Declaration*>* declarations) {
|
||||
for (int i = 0; i < declarations->length(); i++) {
|
||||
@ -2920,13 +2920,13 @@ class AstVisitor BASE_EMBEDDED {
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Subclass* This() { return static_cast<Subclass*>(this); }
|
||||
protected:
|
||||
Subclass* impl() { return static_cast<Subclass*>(this); }
|
||||
};
|
||||
|
||||
#define GENERATE_VISIT_CASE(NodeType) \
|
||||
case AstNode::k##NodeType: \
|
||||
return Visit##NodeType(static_cast<NodeType*>(node));
|
||||
#define GENERATE_VISIT_CASE(NodeType) \
|
||||
case AstNode::k##NodeType: \
|
||||
return this->impl()->Visit##NodeType(static_cast<NodeType*>(node));
|
||||
|
||||
#define GENERATE_AST_VISITOR_SWITCH() \
|
||||
switch (node->node_type()) { \
|
||||
@ -3038,38 +3038,6 @@ class AstVisitor BASE_EMBEDDED {
|
||||
} while (false)
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Traversing visitor
|
||||
// - fully traverses the entire AST.
|
||||
|
||||
// This AstVistor is not final, and provides the AstVisitor methods as virtual
|
||||
// methods so they can be specialized by subclasses.
|
||||
class AstTraversalVisitor : public AstVisitor<AstTraversalVisitor> {
|
||||
public:
|
||||
explicit AstTraversalVisitor(Isolate* isolate);
|
||||
explicit AstTraversalVisitor(uintptr_t stack_limit);
|
||||
virtual ~AstTraversalVisitor() {}
|
||||
|
||||
// Iteration left-to-right.
|
||||
void VisitDeclarations(ZoneList<Declaration*>* declarations);
|
||||
void VisitStatements(ZoneList<Statement*>* statements);
|
||||
|
||||
// Individual nodes
|
||||
#define DECLARE_VISIT(type) virtual void Visit##type(type* node);
|
||||
AST_NODE_LIST(DECLARE_VISIT)
|
||||
#undef DECLARE_VISIT
|
||||
|
||||
protected:
|
||||
int depth() { return depth_; }
|
||||
|
||||
private:
|
||||
DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
|
||||
|
||||
int depth_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AstTraversalVisitor);
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// AstNode factory
|
||||
|
||||
|
@ -1857,7 +1857,7 @@ Handle<JSArray> LiveEditFunctionTracker::Collect(FunctionLiteral* node,
|
||||
|
||||
LiveEditFunctionTracker::LiveEditFunctionTracker(Handle<Script> script,
|
||||
Zone* zone, Isolate* isolate)
|
||||
: AstTraversalVisitor(isolate) {
|
||||
: AstTraversalVisitor<LiveEditFunctionTracker>(isolate) {
|
||||
current_parent_index_ = -1;
|
||||
isolate_ = isolate;
|
||||
len_ = 0;
|
||||
@ -1867,20 +1867,16 @@ LiveEditFunctionTracker::LiveEditFunctionTracker(Handle<Script> script,
|
||||
}
|
||||
|
||||
void LiveEditFunctionTracker::VisitFunctionLiteral(FunctionLiteral* node) {
|
||||
Scope* scope = node->scope();
|
||||
|
||||
// FunctionStarted is called in pre-order.
|
||||
FunctionStarted(node);
|
||||
|
||||
VisitDeclarations(scope->declarations());
|
||||
VisitStatements(node->body());
|
||||
|
||||
// Recurse using the regular traversal.
|
||||
AstTraversalVisitor::VisitFunctionLiteral(node);
|
||||
// FunctionDone are called in post-order.
|
||||
// TODO(jgruber): If required, replace the (linear cost)
|
||||
// FindSharedFunctionInfo call with a more efficient implementation.
|
||||
Handle<SharedFunctionInfo> info =
|
||||
script_->FindSharedFunctionInfo(node).ToHandleChecked();
|
||||
FunctionDone(info, scope);
|
||||
FunctionDone(info, node->scope());
|
||||
}
|
||||
|
||||
void LiveEditFunctionTracker::FunctionStarted(FunctionLiteral* fun) {
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
|
||||
#include "src/allocation.h"
|
||||
#include "src/ast/ast-traversal-visitor.h"
|
||||
#include "src/compiler.h"
|
||||
|
||||
namespace v8 {
|
||||
@ -38,7 +39,8 @@ namespace internal {
|
||||
// in order to analyze whether function code may be safely patched (with new
|
||||
// code successfully reading existing data from function scopes). The Tracker
|
||||
// also collects compiled function codes.
|
||||
class LiveEditFunctionTracker : public AstTraversalVisitor {
|
||||
class LiveEditFunctionTracker
|
||||
: public AstTraversalVisitor<LiveEditFunctionTracker> {
|
||||
public:
|
||||
// Traverses the entire AST, and records information about all
|
||||
// FunctionLiterals for further use by LiveEdit code patching. The collected
|
||||
@ -46,8 +48,9 @@ class LiveEditFunctionTracker : public AstTraversalVisitor {
|
||||
static Handle<JSArray> Collect(FunctionLiteral* node, Handle<Script> script,
|
||||
Zone* zone, Isolate* isolate);
|
||||
|
||||
virtual ~LiveEditFunctionTracker() {}
|
||||
void VisitFunctionLiteral(FunctionLiteral* node) override;
|
||||
protected:
|
||||
friend AstTraversalVisitor<LiveEditFunctionTracker>;
|
||||
void VisitFunctionLiteral(FunctionLiteral* node);
|
||||
|
||||
private:
|
||||
LiveEditFunctionTracker(Handle<Script> script, Zone* zone, Isolate* isolate);
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "src/parsing/parameter-initializer-rewriter.h"
|
||||
|
||||
#include "src/ast/ast.h"
|
||||
#include "src/ast/ast-expression-visitor.h"
|
||||
#include "src/ast/ast-traversal-visitor.h"
|
||||
#include "src/ast/scopes.h"
|
||||
|
||||
namespace v8 {
|
||||
@ -14,22 +14,24 @@ namespace internal {
|
||||
namespace {
|
||||
|
||||
|
||||
class Rewriter final : public AstExpressionVisitor {
|
||||
class Rewriter final : public AstTraversalVisitor<Rewriter> {
|
||||
public:
|
||||
Rewriter(uintptr_t stack_limit, Expression* initializer, Scope* param_scope)
|
||||
: AstExpressionVisitor(stack_limit, initializer),
|
||||
: AstTraversalVisitor(stack_limit, initializer),
|
||||
param_scope_(param_scope) {}
|
||||
|
||||
private:
|
||||
void VisitExpression(Expression* expr) override {}
|
||||
// This is required so that the overriden Visit* methods can be
|
||||
// called by the base class (template).
|
||||
friend class AstTraversalVisitor<Rewriter>;
|
||||
|
||||
void VisitFunctionLiteral(FunctionLiteral* expr) override;
|
||||
void VisitClassLiteral(ClassLiteral* expr) override;
|
||||
void VisitVariableProxy(VariableProxy* expr) override;
|
||||
void VisitFunctionLiteral(FunctionLiteral* expr);
|
||||
void VisitClassLiteral(ClassLiteral* expr);
|
||||
void VisitVariableProxy(VariableProxy* expr);
|
||||
|
||||
void VisitBlock(Block* stmt) override;
|
||||
void VisitTryCatchStatement(TryCatchStatement* stmt) override;
|
||||
void VisitWithStatement(WithStatement* stmt) override;
|
||||
void VisitBlock(Block* stmt);
|
||||
void VisitTryCatchStatement(TryCatchStatement* stmt);
|
||||
void VisitWithStatement(WithStatement* stmt);
|
||||
|
||||
Scope* param_scope_;
|
||||
};
|
||||
|
@ -7,8 +7,8 @@
|
||||
#include "src/api.h"
|
||||
#include "src/ast/ast.h"
|
||||
#include "src/ast/ast-expression-rewriter.h"
|
||||
#include "src/ast/ast-expression-visitor.h"
|
||||
#include "src/ast/ast-literal-reindexer.h"
|
||||
#include "src/ast/ast-traversal-visitor.h"
|
||||
#include "src/ast/scopeinfo.h"
|
||||
#include "src/bailout-reason.h"
|
||||
#include "src/base/platform/platform.h"
|
||||
@ -4631,28 +4631,31 @@ Statement* Parser::BuildAssertIsCoercible(Variable* var) {
|
||||
}
|
||||
|
||||
|
||||
class InitializerRewriter : public AstExpressionVisitor {
|
||||
class InitializerRewriter final
|
||||
: public AstTraversalVisitor<InitializerRewriter> {
|
||||
public:
|
||||
InitializerRewriter(uintptr_t stack_limit, Expression* root, Parser* parser,
|
||||
Scope* scope)
|
||||
: AstExpressionVisitor(stack_limit, root),
|
||||
: AstTraversalVisitor(stack_limit, root),
|
||||
parser_(parser),
|
||||
scope_(scope) {}
|
||||
|
||||
private:
|
||||
void VisitExpression(Expression* expr) override {
|
||||
RewritableExpression* to_rewrite = expr->AsRewritableExpression();
|
||||
if (to_rewrite == nullptr || to_rewrite->is_rewritten()) return;
|
||||
// This is required so that the overriden Visit* methods can be
|
||||
// called by the base class (template).
|
||||
friend class AstTraversalVisitor<InitializerRewriter>;
|
||||
|
||||
// Just rewrite destructuring assignments wrapped in RewritableExpressions.
|
||||
void VisitRewritableExpression(RewritableExpression* to_rewrite) {
|
||||
if (to_rewrite->is_rewritten()) return;
|
||||
Parser::PatternRewriter::RewriteDestructuringAssignment(parser_, to_rewrite,
|
||||
scope_);
|
||||
}
|
||||
|
||||
// Code in function literals does not need to be eagerly rewritten, it will be
|
||||
// rewritten when scheduled.
|
||||
void VisitFunctionLiteral(FunctionLiteral* expr) override {}
|
||||
void VisitFunctionLiteral(FunctionLiteral* expr) {}
|
||||
|
||||
private:
|
||||
Parser* parser_;
|
||||
Scope* scope_;
|
||||
};
|
||||
|
@ -853,7 +853,7 @@ class Parser : public ParserBase<ParserTraits> {
|
||||
Scanner::Location bindings_loc;
|
||||
};
|
||||
|
||||
class PatternRewriter final : private AstVisitor<PatternRewriter> {
|
||||
class PatternRewriter final : public AstVisitor<PatternRewriter> {
|
||||
public:
|
||||
static void DeclareAndInitializeVariables(
|
||||
Block* block, const DeclarationDescriptor* declaration_descriptor,
|
||||
|
@ -451,12 +451,11 @@
|
||||
'assert-scope.cc',
|
||||
'ast/ast-expression-rewriter.cc',
|
||||
'ast/ast-expression-rewriter.h',
|
||||
'ast/ast-expression-visitor.cc',
|
||||
'ast/ast-expression-visitor.h',
|
||||
'ast/ast-literal-reindexer.cc',
|
||||
'ast/ast-literal-reindexer.h',
|
||||
'ast/ast-numbering.cc',
|
||||
'ast/ast-numbering.h',
|
||||
'ast/ast-traversal-visitor.h',
|
||||
'ast/ast-type-bounds.h',
|
||||
'ast/ast-value-factory.cc',
|
||||
'ast/ast-value-factory.h',
|
||||
|
Loading…
Reference in New Issue
Block a user