Commit 9439a1d2 authored by Toon Verwaest's avatar Toon Verwaest Committed by Commit Bot

[ast] Always visit all AST nodes, even dead nodes

We'll let the bytecode compiler and optimizing compilers deal with dead code,
rather than the ast visitors. The problem is that the visitors previously
disagreed upon what was dead. That's bad if necessary visitors omit parts of
the code that the bytecode generator will actually visit.

I did consider removing the AST nodes immediately in the parser, but that
adds overhead and actually broke code coverage. Since dead code shouldn't be
shipped to the browser anyway (and we can still omit it later in the bytecode
generator), I opted for keeping the nodes instead.

Change-Id: Ib02fa9031b17556d2e1d46af6648356486f8433d
Reviewed-on: https://chromium-review.googlesource.com/c/1470108
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59569}
parent 2cf62329
......@@ -116,7 +116,6 @@ void AstTraversalVisitor<Subclass>::VisitStatements(
for (int i = 0; i < stmts->length(); ++i) {
Statement* stmt = stmts->at(i);
RECURSE(Visit(stmt));
if (stmt->IsJump()) break;
}
}
......
......@@ -151,26 +151,6 @@ bool Expression::IsAccessorFunctionDefinition() const {
return IsFunctionLiteral() && IsAccessorFunction(AsFunctionLiteral()->kind());
}
bool Statement::IsJump() const {
switch (node_type()) {
#define JUMP_NODE_LIST(V) \
V(Block) \
V(ExpressionStatement) \
V(ContinueStatement) \
V(BreakStatement) \
V(ReturnStatement) \
V(IfStatement)
#define GENERATE_CASE(Node) \
case k##Node: \
return static_cast<const Node*>(this)->IsJump();
JUMP_NODE_LIST(GENERATE_CASE)
#undef GENERATE_CASE
#undef JUMP_NODE_LIST
default:
return false;
}
}
VariableProxy::VariableProxy(Variable* var, int start_position)
: Expression(start_position, kVariableProxy),
raw_name_(var->raw_name()),
......
......@@ -180,9 +180,6 @@ class AstNode: public ZoneObject {
class Statement : public AstNode {
public:
bool IsJump() const;
protected:
Statement(int position, NodeType type) : AstNode(position, type) {}
......@@ -342,11 +339,6 @@ class Block : public BreakableStatement {
inline ZonePtrList<const AstRawString>* labels() const;
bool IsJump() const {
return !statements_.is_empty() && statements_.last()->IsJump() &&
labels() == nullptr; // Good enough as an approximation...
}
Scope* scope() const { return scope_; }
void set_scope(Scope* scope) { scope_ = scope; }
......@@ -677,7 +669,6 @@ class ExpressionStatement final : public Statement {
public:
void set_expression(Expression* e) { expression_ = e; }
Expression* expression() const { return expression_; }
bool IsJump() const { return expression_->IsThrow(); }
private:
friend class AstNodeFactory;
......@@ -690,9 +681,6 @@ class ExpressionStatement final : public Statement {
class JumpStatement : public Statement {
public:
bool IsJump() const { return true; }
protected:
JumpStatement(int pos, NodeType type) : Statement(pos, type) {}
};
......@@ -838,11 +826,6 @@ class IfStatement final : public Statement {
void set_then_statement(Statement* s) { then_statement_ = s; }
void set_else_statement(Statement* s) { else_statement_ = s; }
bool IsJump() const {
return HasThenStatement() && then_statement()->IsJump()
&& HasElseStatement() && else_statement()->IsJump();
}
private:
friend class AstNodeFactory;
......@@ -2702,7 +2685,6 @@ class AstVisitor {
for (int i = 0; i < statements->length(); i++) {
Statement* stmt = statements->at(i);
Visit(stmt);
if (stmt->IsJump()) break;
}
}
......
......@@ -782,6 +782,8 @@ const char* AstPrinter::PrintProgram(FunctionLiteral* program) {
{ IndentedScope indent(this, "FUNC", program->position());
PrintIndented("KIND");
Print(" %d\n", program->kind());
PrintIndented("LITERAL ID");
Print(" %d\n", program->function_literal_id());
PrintIndented("SUSPEND COUNT");
Print(" %d\n", program->suspend_count());
PrintLiteralIndented("NAME", program->raw_name(), true);
......@@ -1033,6 +1035,8 @@ void AstPrinter::VisitDebuggerStatement(DebuggerStatement* node) {
void AstPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
IndentedScope indent(this, "FUNC LITERAL", node->position());
PrintIndented("LITERAL ID");
Print(" %d\n", node->function_literal_id());
PrintLiteralIndented("NAME", node->raw_name(), false);
PrintLiteralIndented("INFERRED NAME", node->raw_inferred_name(), false);
// We don't want to see the function literal in this case: it
......
// Copyright 2019 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.
var asdf = false;
const f =
(v1 = (function g() {
if (asdf) { return; } else { return; }
(function h() {});
})()) => 1;
f();
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