9365d0904e
This changes a few bits about how continuation counters are handled. It introduces a new mechanism that allows removal of a continuation range after it has been created. If coverage is enabled, we run a first post-processing pass on the AST immediately after parsing, which removes problematic continuation ranges in two situations: 1. nested continuation counters - only the outermost stays alive. 2. trailing continuation counters within a block-like structure are removed if the containing structure itself has a continuation. R=bmeurer@chromium.org, jgruber@chromium.org, yangguo@chromium.org Bug: v8:8381, v8:8539 Change-Id: I6bcaea5060d8c481d7bae099f6db9f993cc30ee3 Reviewed-on: https://chromium-review.googlesource.com/c/1339119 Reviewed-by: Yang Guo <yangguo@chromium.org> Reviewed-by: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#58443}
69 lines
2.3 KiB
C++
69 lines
2.3 KiB
C++
// Copyright 2018 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/ast/source-range-ast-visitor.h"
|
|
|
|
#include "src/ast/ast-source-ranges.h"
|
|
|
|
namespace v8 {
|
|
namespace internal {
|
|
|
|
SourceRangeAstVisitor::SourceRangeAstVisitor(uintptr_t stack_limit,
|
|
Expression* root,
|
|
SourceRangeMap* source_range_map)
|
|
: AstTraversalVisitor(stack_limit, root),
|
|
source_range_map_(source_range_map) {}
|
|
|
|
void SourceRangeAstVisitor::VisitBlock(Block* stmt) {
|
|
AstTraversalVisitor::VisitBlock(stmt);
|
|
ZonePtrList<Statement>* stmts = stmt->statements();
|
|
AstNodeSourceRanges* enclosingSourceRanges = source_range_map_->Find(stmt);
|
|
if (enclosingSourceRanges != nullptr) {
|
|
CHECK(enclosingSourceRanges->HasRange(SourceRangeKind::kContinuation));
|
|
MaybeRemoveLastContinuationRange(stmts);
|
|
}
|
|
}
|
|
|
|
void SourceRangeAstVisitor::VisitFunctionLiteral(FunctionLiteral* expr) {
|
|
AstTraversalVisitor::VisitFunctionLiteral(expr);
|
|
ZonePtrList<Statement>* stmts = expr->body();
|
|
MaybeRemoveLastContinuationRange(stmts);
|
|
}
|
|
|
|
bool SourceRangeAstVisitor::VisitNode(AstNode* node) {
|
|
AstNodeSourceRanges* range = source_range_map_->Find(node);
|
|
|
|
if (range == nullptr) return true;
|
|
if (!range->HasRange(SourceRangeKind::kContinuation)) return true;
|
|
|
|
// Called in pre-order. In case of conflicting continuation ranges, only the
|
|
// outermost range may survive.
|
|
|
|
SourceRange continuation = range->GetRange(SourceRangeKind::kContinuation);
|
|
if (continuation_positions_.find(continuation.start) !=
|
|
continuation_positions_.end()) {
|
|
range->RemoveContinuationRange();
|
|
} else {
|
|
continuation_positions_.emplace(continuation.start);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void SourceRangeAstVisitor::MaybeRemoveLastContinuationRange(
|
|
ZonePtrList<Statement>* statements) {
|
|
if (statements->is_empty()) return;
|
|
|
|
Statement* last_statement = statements->last();
|
|
AstNodeSourceRanges* last_range = source_range_map_->Find(last_statement);
|
|
if (last_range == nullptr) return;
|
|
|
|
if (last_range->HasRange(SourceRangeKind::kContinuation)) {
|
|
last_range->RemoveContinuationRange();
|
|
}
|
|
}
|
|
|
|
} // namespace internal
|
|
} // namespace v8
|