Revert "[coverage] add coverage for binary expressions"
This reverts commit 4d3bc552b5
.
Reason for revert: https://crbug.com/785778
Original change's description:
> [coverage] add coverage for binary expressions
>
> Adds block-level coverage tracking for binary && and ||
> expressions. Introduces a BinaryOperation source-range
> for tracking the operations themselves and an Expression
> source-range, used for tracking NaryLogical expressions.
>
> This builds on work by jgruber@chromium.org in
> the issue.
>
> TBR=marja@chromium.org
> R=jgruber@chromium.org, rmcilroy@chromium.org
>
> Bug: v8:6660
> Change-Id: I83a81f13a3514a734c06948b2d3e91138fb00e18
> Reviewed-on: https://chromium-review.googlesource.com/754564
> Commit-Queue: Jakob Gruber <jgruber@chromium.org>
> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
> Reviewed-by: Jakob Gruber <jgruber@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#49304}
TBR=rmcilroy@chromium.org,marja@chromium.org,jgruber@chromium.org,ben@npmjs.com
# Not skipping CQ checks because original CL landed > 1 day ago.
Bug: v8:6660
Change-Id: Ie017c528604b2e01400f527511413eaea5786198
Reviewed-on: https://chromium-review.googlesource.com/776768
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49454}
This commit is contained in:
parent
d42534d441
commit
9037639eb1
1
AUTHORS
1
AUTHORS
@ -46,7 +46,6 @@ Andrew Paprocki <andrew@ishiboo.com>
|
|||||||
Andrei Kashcha <anvaka@gmail.com>
|
Andrei Kashcha <anvaka@gmail.com>
|
||||||
Anna Henningsen <addaleax@gmail.com>
|
Anna Henningsen <addaleax@gmail.com>
|
||||||
Bangfu Tao <bangfu.tao@samsung.com>
|
Bangfu Tao <bangfu.tao@samsung.com>
|
||||||
Ben Coe <ben@npmjs.com>
|
|
||||||
Ben Noordhuis <info@bnoordhuis.nl>
|
Ben Noordhuis <info@bnoordhuis.nl>
|
||||||
Benjamin Tan <demoneaux@gmail.com>
|
Benjamin Tan <demoneaux@gmail.com>
|
||||||
Bert Belder <bertbelder@gmail.com>
|
Bert Belder <bertbelder@gmail.com>
|
||||||
|
@ -33,7 +33,6 @@ struct SourceRange {
|
|||||||
V(Block) \
|
V(Block) \
|
||||||
V(CaseClause) \
|
V(CaseClause) \
|
||||||
V(Conditional) \
|
V(Conditional) \
|
||||||
V(Expression) \
|
|
||||||
V(IfStatement) \
|
V(IfStatement) \
|
||||||
V(IterationStatement) \
|
V(IterationStatement) \
|
||||||
V(JumpStatement) \
|
V(JumpStatement) \
|
||||||
@ -114,20 +113,6 @@ class ConditionalSourceRanges final : public AstNodeSourceRanges {
|
|||||||
SourceRange else_range_;
|
SourceRange else_range_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ExpressionSourceRanges final : public AstNodeSourceRanges {
|
|
||||||
public:
|
|
||||||
explicit ExpressionSourceRanges(const SourceRange& body_range)
|
|
||||||
: body_range_(body_range) {}
|
|
||||||
|
|
||||||
SourceRange GetRange(SourceRangeKind kind) {
|
|
||||||
DCHECK_EQ(kind, SourceRangeKind::kBody);
|
|
||||||
return body_range_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
SourceRange body_range_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class IfStatementSourceRanges final : public AstNodeSourceRanges {
|
class IfStatementSourceRanges final : public AstNodeSourceRanges {
|
||||||
public:
|
public:
|
||||||
explicit IfStatementSourceRanges(const SourceRange& then_range,
|
explicit IfStatementSourceRanges(const SourceRange& then_range,
|
||||||
|
@ -494,32 +494,6 @@ class BytecodeGenerator::ControlScopeForTryFinally final
|
|||||||
DeferredCommands* commands_;
|
DeferredCommands* commands_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Allocate and fetch the coverage indices tracking NaryLogical Expressions.
|
|
||||||
class BytecodeGenerator::NArayCodeCoverageSlots {
|
|
||||||
public:
|
|
||||||
explicit NArayCodeCoverageSlots(BytecodeGenerator* generator,
|
|
||||||
NaryOperation* expr)
|
|
||||||
: generator_(generator) {
|
|
||||||
if (generator_->block_coverage_builder_ == nullptr) return;
|
|
||||||
for (size_t i = 0; i < expr->subsequent_length(); i++) {
|
|
||||||
coverage_slots_.push_back(generator_->AllocateBlockCoverageSlotIfEnabled(
|
|
||||||
expr->subsequent(i), SourceRangeKind::kBody));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int GetSlotFor(size_t subsequent_expr_index) const {
|
|
||||||
if (generator_->block_coverage_builder_ == nullptr) {
|
|
||||||
return BlockCoverageBuilder::kNoCoverageArraySlot;
|
|
||||||
}
|
|
||||||
DCHECK(coverage_slots_.size() > subsequent_expr_index);
|
|
||||||
return coverage_slots_[subsequent_expr_index];
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
BytecodeGenerator* generator_;
|
|
||||||
std::vector<int> coverage_slots_;
|
|
||||||
};
|
|
||||||
|
|
||||||
void BytecodeGenerator::ControlScope::PerformCommand(Command command,
|
void BytecodeGenerator::ControlScope::PerformCommand(Command command,
|
||||||
Statement* statement,
|
Statement* statement,
|
||||||
int source_position) {
|
int source_position) {
|
||||||
@ -4123,7 +4097,7 @@ void BytecodeGenerator::VisitNaryCommaExpression(NaryOperation* expr) {
|
|||||||
|
|
||||||
void BytecodeGenerator::VisitLogicalTestSubExpression(
|
void BytecodeGenerator::VisitLogicalTestSubExpression(
|
||||||
Token::Value token, Expression* expr, BytecodeLabels* then_labels,
|
Token::Value token, Expression* expr, BytecodeLabels* then_labels,
|
||||||
BytecodeLabels* else_labels, int coverage_slot) {
|
BytecodeLabels* else_labels) {
|
||||||
DCHECK(token == Token::OR || token == Token::AND);
|
DCHECK(token == Token::OR || token == Token::AND);
|
||||||
|
|
||||||
BytecodeLabels test_next(zone());
|
BytecodeLabels test_next(zone());
|
||||||
@ -4134,28 +4108,23 @@ void BytecodeGenerator::VisitLogicalTestSubExpression(
|
|||||||
VisitForTest(expr, &test_next, else_labels, TestFallthrough::kThen);
|
VisitForTest(expr, &test_next, else_labels, TestFallthrough::kThen);
|
||||||
}
|
}
|
||||||
test_next.Bind(builder());
|
test_next.Bind(builder());
|
||||||
|
|
||||||
BuildIncrementBlockCoverageCounterIfEnabled(coverage_slot);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BytecodeGenerator::VisitLogicalTest(Token::Value token, Expression* left,
|
void BytecodeGenerator::VisitLogicalTest(Token::Value token, Expression* left,
|
||||||
Expression* right,
|
Expression* right) {
|
||||||
int right_coverage_slot) {
|
|
||||||
DCHECK(token == Token::OR || token == Token::AND);
|
DCHECK(token == Token::OR || token == Token::AND);
|
||||||
TestResultScope* test_result = execution_result()->AsTest();
|
TestResultScope* test_result = execution_result()->AsTest();
|
||||||
BytecodeLabels* then_labels = test_result->then_labels();
|
BytecodeLabels* then_labels = test_result->then_labels();
|
||||||
BytecodeLabels* else_labels = test_result->else_labels();
|
BytecodeLabels* else_labels = test_result->else_labels();
|
||||||
TestFallthrough fallthrough = test_result->fallthrough();
|
TestFallthrough fallthrough = test_result->fallthrough();
|
||||||
|
|
||||||
VisitLogicalTestSubExpression(token, left, then_labels, else_labels,
|
VisitLogicalTestSubExpression(token, left, then_labels, else_labels);
|
||||||
right_coverage_slot);
|
|
||||||
// The last test has the same then, else and fallthrough as the parent test.
|
// The last test has the same then, else and fallthrough as the parent test.
|
||||||
VisitForTest(right, then_labels, else_labels, fallthrough);
|
VisitForTest(right, then_labels, else_labels, fallthrough);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BytecodeGenerator::VisitNaryLogicalTest(
|
void BytecodeGenerator::VisitNaryLogicalTest(Token::Value token,
|
||||||
Token::Value token, NaryOperation* expr,
|
NaryOperation* expr) {
|
||||||
const NArayCodeCoverageSlots* coverage_slots) {
|
|
||||||
DCHECK(token == Token::OR || token == Token::AND);
|
DCHECK(token == Token::OR || token == Token::AND);
|
||||||
DCHECK_GT(expr->subsequent_length(), 0);
|
DCHECK_GT(expr->subsequent_length(), 0);
|
||||||
|
|
||||||
@ -4164,21 +4133,18 @@ void BytecodeGenerator::VisitNaryLogicalTest(
|
|||||||
BytecodeLabels* else_labels = test_result->else_labels();
|
BytecodeLabels* else_labels = test_result->else_labels();
|
||||||
TestFallthrough fallthrough = test_result->fallthrough();
|
TestFallthrough fallthrough = test_result->fallthrough();
|
||||||
|
|
||||||
VisitLogicalTestSubExpression(token, expr->first(), then_labels, else_labels,
|
VisitLogicalTestSubExpression(token, expr->first(), then_labels, else_labels);
|
||||||
coverage_slots->GetSlotFor(0));
|
|
||||||
for (size_t i = 0; i < expr->subsequent_length() - 1; ++i) {
|
for (size_t i = 0; i < expr->subsequent_length() - 1; ++i) {
|
||||||
VisitLogicalTestSubExpression(token, expr->subsequent(i), then_labels,
|
VisitLogicalTestSubExpression(token, expr->subsequent(i), then_labels,
|
||||||
else_labels,
|
else_labels);
|
||||||
coverage_slots->GetSlotFor(i + 1));
|
|
||||||
}
|
}
|
||||||
// The last test has the same then, else and fallthrough as the parent test.
|
// The last test has the same then, else and fallthrough as the parent test.
|
||||||
VisitForTest(expr->subsequent(expr->subsequent_length() - 1), then_labels,
|
VisitForTest(expr->subsequent(expr->subsequent_length() - 1), then_labels,
|
||||||
else_labels, fallthrough);
|
else_labels, fallthrough);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BytecodeGenerator::VisitLogicalOrSubExpression(Expression* expr,
|
bool BytecodeGenerator::VisitLogicalOrSubExpression(
|
||||||
BytecodeLabels* end_labels,
|
Expression* expr, BytecodeLabels* end_labels) {
|
||||||
int coverage_slot) {
|
|
||||||
if (expr->ToBooleanIsTrue()) {
|
if (expr->ToBooleanIsTrue()) {
|
||||||
VisitForAccumulatorValue(expr);
|
VisitForAccumulatorValue(expr);
|
||||||
end_labels->Bind(builder());
|
end_labels->Bind(builder());
|
||||||
@ -4188,15 +4154,11 @@ bool BytecodeGenerator::VisitLogicalOrSubExpression(Expression* expr,
|
|||||||
builder()->JumpIfTrue(ToBooleanModeFromTypeHint(type_hint),
|
builder()->JumpIfTrue(ToBooleanModeFromTypeHint(type_hint),
|
||||||
end_labels->New());
|
end_labels->New());
|
||||||
}
|
}
|
||||||
|
|
||||||
BuildIncrementBlockCoverageCounterIfEnabled(coverage_slot);
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BytecodeGenerator::VisitLogicalAndSubExpression(Expression* expr,
|
bool BytecodeGenerator::VisitLogicalAndSubExpression(
|
||||||
BytecodeLabels* end_labels,
|
Expression* expr, BytecodeLabels* end_labels) {
|
||||||
int coverage_slot) {
|
|
||||||
if (expr->ToBooleanIsFalse()) {
|
if (expr->ToBooleanIsFalse()) {
|
||||||
VisitForAccumulatorValue(expr);
|
VisitForAccumulatorValue(expr);
|
||||||
end_labels->Bind(builder());
|
end_labels->Bind(builder());
|
||||||
@ -4206,9 +4168,6 @@ bool BytecodeGenerator::VisitLogicalAndSubExpression(Expression* expr,
|
|||||||
builder()->JumpIfFalse(ToBooleanModeFromTypeHint(type_hint),
|
builder()->JumpIfFalse(ToBooleanModeFromTypeHint(type_hint),
|
||||||
end_labels->New());
|
end_labels->New());
|
||||||
}
|
}
|
||||||
|
|
||||||
BuildIncrementBlockCoverageCounterIfEnabled(coverage_slot);
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4216,25 +4175,19 @@ void BytecodeGenerator::VisitLogicalOrExpression(BinaryOperation* binop) {
|
|||||||
Expression* left = binop->left();
|
Expression* left = binop->left();
|
||||||
Expression* right = binop->right();
|
Expression* right = binop->right();
|
||||||
|
|
||||||
int right_coverage_slot =
|
|
||||||
AllocateBlockCoverageSlotIfEnabled(right, SourceRangeKind::kBody);
|
|
||||||
|
|
||||||
if (execution_result()->IsTest()) {
|
if (execution_result()->IsTest()) {
|
||||||
TestResultScope* test_result = execution_result()->AsTest();
|
TestResultScope* test_result = execution_result()->AsTest();
|
||||||
if (left->ToBooleanIsTrue()) {
|
if (left->ToBooleanIsTrue()) {
|
||||||
builder()->Jump(test_result->NewThenLabel());
|
builder()->Jump(test_result->NewThenLabel());
|
||||||
} else if (left->ToBooleanIsFalse() && right->ToBooleanIsFalse()) {
|
} else if (left->ToBooleanIsFalse() && right->ToBooleanIsFalse()) {
|
||||||
BuildIncrementBlockCoverageCounterIfEnabled(right_coverage_slot);
|
|
||||||
builder()->Jump(test_result->NewElseLabel());
|
builder()->Jump(test_result->NewElseLabel());
|
||||||
} else {
|
} else {
|
||||||
VisitLogicalTest(Token::OR, left, right, right_coverage_slot);
|
VisitLogicalTest(Token::OR, left, right);
|
||||||
}
|
}
|
||||||
test_result->SetResultConsumedByTest();
|
test_result->SetResultConsumedByTest();
|
||||||
} else {
|
} else {
|
||||||
BytecodeLabels end_labels(zone());
|
BytecodeLabels end_labels(zone());
|
||||||
if (VisitLogicalOrSubExpression(left, &end_labels, right_coverage_slot)) {
|
if (VisitLogicalOrSubExpression(left, &end_labels)) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
VisitForAccumulatorValue(right);
|
VisitForAccumulatorValue(right);
|
||||||
end_labels.Bind(builder());
|
end_labels.Bind(builder());
|
||||||
}
|
}
|
||||||
@ -4244,25 +4197,19 @@ void BytecodeGenerator::VisitNaryLogicalOrExpression(NaryOperation* expr) {
|
|||||||
Expression* first = expr->first();
|
Expression* first = expr->first();
|
||||||
DCHECK_GT(expr->subsequent_length(), 0);
|
DCHECK_GT(expr->subsequent_length(), 0);
|
||||||
|
|
||||||
NArayCodeCoverageSlots coverage_slots(this, expr);
|
|
||||||
|
|
||||||
if (execution_result()->IsTest()) {
|
if (execution_result()->IsTest()) {
|
||||||
TestResultScope* test_result = execution_result()->AsTest();
|
TestResultScope* test_result = execution_result()->AsTest();
|
||||||
if (first->ToBooleanIsTrue()) {
|
if (first->ToBooleanIsTrue()) {
|
||||||
builder()->Jump(test_result->NewThenLabel());
|
builder()->Jump(test_result->NewThenLabel());
|
||||||
} else {
|
} else {
|
||||||
VisitNaryLogicalTest(Token::OR, expr, &coverage_slots);
|
VisitNaryLogicalTest(Token::OR, expr);
|
||||||
}
|
}
|
||||||
test_result->SetResultConsumedByTest();
|
test_result->SetResultConsumedByTest();
|
||||||
} else {
|
} else {
|
||||||
BytecodeLabels end_labels(zone());
|
BytecodeLabels end_labels(zone());
|
||||||
if (VisitLogicalOrSubExpression(first, &end_labels,
|
if (VisitLogicalOrSubExpression(first, &end_labels)) return;
|
||||||
coverage_slots.GetSlotFor(0))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (size_t i = 0; i < expr->subsequent_length() - 1; ++i) {
|
for (size_t i = 0; i < expr->subsequent_length() - 1; ++i) {
|
||||||
if (VisitLogicalOrSubExpression(expr->subsequent(i), &end_labels,
|
if (VisitLogicalOrSubExpression(expr->subsequent(i), &end_labels)) {
|
||||||
coverage_slots.GetSlotFor(i + 1))) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4277,25 +4224,19 @@ void BytecodeGenerator::VisitLogicalAndExpression(BinaryOperation* binop) {
|
|||||||
Expression* left = binop->left();
|
Expression* left = binop->left();
|
||||||
Expression* right = binop->right();
|
Expression* right = binop->right();
|
||||||
|
|
||||||
int right_coverage_slot =
|
|
||||||
AllocateBlockCoverageSlotIfEnabled(right, SourceRangeKind::kBody);
|
|
||||||
|
|
||||||
if (execution_result()->IsTest()) {
|
if (execution_result()->IsTest()) {
|
||||||
TestResultScope* test_result = execution_result()->AsTest();
|
TestResultScope* test_result = execution_result()->AsTest();
|
||||||
if (left->ToBooleanIsFalse()) {
|
if (left->ToBooleanIsFalse()) {
|
||||||
builder()->Jump(test_result->NewElseLabel());
|
builder()->Jump(test_result->NewElseLabel());
|
||||||
} else if (left->ToBooleanIsTrue() && right->ToBooleanIsTrue()) {
|
} else if (left->ToBooleanIsTrue() && right->ToBooleanIsTrue()) {
|
||||||
BuildIncrementBlockCoverageCounterIfEnabled(right_coverage_slot);
|
|
||||||
builder()->Jump(test_result->NewThenLabel());
|
builder()->Jump(test_result->NewThenLabel());
|
||||||
} else {
|
} else {
|
||||||
VisitLogicalTest(Token::AND, left, right, right_coverage_slot);
|
VisitLogicalTest(Token::AND, left, right);
|
||||||
}
|
}
|
||||||
test_result->SetResultConsumedByTest();
|
test_result->SetResultConsumedByTest();
|
||||||
} else {
|
} else {
|
||||||
BytecodeLabels end_labels(zone());
|
BytecodeLabels end_labels(zone());
|
||||||
if (VisitLogicalAndSubExpression(left, &end_labels, right_coverage_slot)) {
|
if (VisitLogicalAndSubExpression(left, &end_labels)) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
VisitForAccumulatorValue(right);
|
VisitForAccumulatorValue(right);
|
||||||
end_labels.Bind(builder());
|
end_labels.Bind(builder());
|
||||||
}
|
}
|
||||||
@ -4305,25 +4246,19 @@ void BytecodeGenerator::VisitNaryLogicalAndExpression(NaryOperation* expr) {
|
|||||||
Expression* first = expr->first();
|
Expression* first = expr->first();
|
||||||
DCHECK_GT(expr->subsequent_length(), 0);
|
DCHECK_GT(expr->subsequent_length(), 0);
|
||||||
|
|
||||||
NArayCodeCoverageSlots coverage_slots(this, expr);
|
|
||||||
|
|
||||||
if (execution_result()->IsTest()) {
|
if (execution_result()->IsTest()) {
|
||||||
TestResultScope* test_result = execution_result()->AsTest();
|
TestResultScope* test_result = execution_result()->AsTest();
|
||||||
if (first->ToBooleanIsFalse()) {
|
if (first->ToBooleanIsFalse()) {
|
||||||
builder()->Jump(test_result->NewElseLabel());
|
builder()->Jump(test_result->NewElseLabel());
|
||||||
} else {
|
} else {
|
||||||
VisitNaryLogicalTest(Token::AND, expr, &coverage_slots);
|
VisitNaryLogicalTest(Token::AND, expr);
|
||||||
}
|
}
|
||||||
test_result->SetResultConsumedByTest();
|
test_result->SetResultConsumedByTest();
|
||||||
} else {
|
} else {
|
||||||
BytecodeLabels end_labels(zone());
|
BytecodeLabels end_labels(zone());
|
||||||
if (VisitLogicalAndSubExpression(first, &end_labels,
|
if (VisitLogicalAndSubExpression(first, &end_labels)) return;
|
||||||
coverage_slots.GetSlotFor(0))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (size_t i = 0; i < expr->subsequent_length() - 1; ++i) {
|
for (size_t i = 0; i < expr->subsequent_length() - 1; ++i) {
|
||||||
if (VisitLogicalAndSubExpression(expr->subsequent(i), &end_labels,
|
if (VisitLogicalAndSubExpression(expr->subsequent(i), &end_labels)) {
|
||||||
coverage_slots.GetSlotFor(i + 1))) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,6 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
|
|||||||
class EffectResultScope;
|
class EffectResultScope;
|
||||||
class FeedbackSlotCache;
|
class FeedbackSlotCache;
|
||||||
class GlobalDeclarationsBuilder;
|
class GlobalDeclarationsBuilder;
|
||||||
class NArayCodeCoverageSlots;
|
|
||||||
class RegisterAllocationScope;
|
class RegisterAllocationScope;
|
||||||
class TestResultScope;
|
class TestResultScope;
|
||||||
class ValueResultScope;
|
class ValueResultScope;
|
||||||
@ -175,23 +174,20 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
|
|||||||
|
|
||||||
// Visit a logical OR/AND within a test context, rewiring the jumps based
|
// Visit a logical OR/AND within a test context, rewiring the jumps based
|
||||||
// on the expression values.
|
// on the expression values.
|
||||||
void VisitLogicalTest(Token::Value token, Expression* left, Expression* right,
|
void VisitLogicalTest(Token::Value token, Expression* left,
|
||||||
int right_coverage_slot);
|
Expression* right);
|
||||||
void VisitNaryLogicalTest(Token::Value token, NaryOperation* expr,
|
void VisitNaryLogicalTest(Token::Value token, NaryOperation* expr);
|
||||||
const NArayCodeCoverageSlots* coverage_slots);
|
|
||||||
// Visit a (non-RHS) test for a logical op, which falls through if the test
|
// Visit a (non-RHS) test for a logical op, which falls through if the test
|
||||||
// fails or jumps to the appropriate labels if it succeeds.
|
// fails or jumps to the appropriate labels if it succeeds.
|
||||||
void VisitLogicalTestSubExpression(Token::Value token, Expression* expr,
|
void VisitLogicalTestSubExpression(Token::Value token, Expression* expr,
|
||||||
BytecodeLabels* then_labels,
|
BytecodeLabels* then_labels,
|
||||||
BytecodeLabels* else_labels,
|
BytecodeLabels* else_labels);
|
||||||
int coverage_slot);
|
|
||||||
|
|
||||||
// Helpers for binary and nary logical op value expressions.
|
// Helpers for binary and nary logical op value expressions.
|
||||||
bool VisitLogicalOrSubExpression(Expression* expr, BytecodeLabels* end_labels,
|
bool VisitLogicalOrSubExpression(Expression* expr,
|
||||||
int coverage_slot);
|
BytecodeLabels* end_labels);
|
||||||
bool VisitLogicalAndSubExpression(Expression* expr,
|
bool VisitLogicalAndSubExpression(Expression* expr,
|
||||||
BytecodeLabels* end_labels,
|
BytecodeLabels* end_labels);
|
||||||
int coverage_slot);
|
|
||||||
|
|
||||||
// Visit the header/body of a loop iteration.
|
// Visit the header/body of a loop iteration.
|
||||||
void VisitIterationHeader(IterationStatement* stmt,
|
void VisitIterationHeader(IterationStatement* stmt,
|
||||||
@ -208,7 +204,6 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
|
|||||||
void BuildLoadPropertyKey(LiteralProperty* property, Register out_reg);
|
void BuildLoadPropertyKey(LiteralProperty* property, Register out_reg);
|
||||||
|
|
||||||
int AllocateBlockCoverageSlotIfEnabled(AstNode* node, SourceRangeKind kind);
|
int AllocateBlockCoverageSlotIfEnabled(AstNode* node, SourceRangeKind kind);
|
||||||
|
|
||||||
void BuildIncrementBlockCoverageCounterIfEnabled(AstNode* node,
|
void BuildIncrementBlockCoverageCounterIfEnabled(AstNode* node,
|
||||||
SourceRangeKind kind);
|
SourceRangeKind kind);
|
||||||
void BuildIncrementBlockCoverageCounterIfEnabled(int coverage_array_slot);
|
void BuildIncrementBlockCoverageCounterIfEnabled(int coverage_array_slot);
|
||||||
|
@ -3081,7 +3081,6 @@ template <typename Impl>
|
|||||||
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBinaryExpression(
|
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBinaryExpression(
|
||||||
int prec, bool accept_IN, bool* ok) {
|
int prec, bool accept_IN, bool* ok) {
|
||||||
DCHECK_GE(prec, 4);
|
DCHECK_GE(prec, 4);
|
||||||
SourceRange right_range;
|
|
||||||
ExpressionT x = ParseUnaryExpression(CHECK_OK);
|
ExpressionT x = ParseUnaryExpression(CHECK_OK);
|
||||||
for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
|
for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
|
||||||
// prec1 >= 4
|
// prec1 >= 4
|
||||||
@ -3089,25 +3088,18 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBinaryExpression(
|
|||||||
impl()->RewriteNonPattern(CHECK_OK);
|
impl()->RewriteNonPattern(CHECK_OK);
|
||||||
BindingPatternUnexpectedToken();
|
BindingPatternUnexpectedToken();
|
||||||
ArrowFormalParametersUnexpectedToken();
|
ArrowFormalParametersUnexpectedToken();
|
||||||
|
|
||||||
SourceRangeScope right_range_scope(scanner(), &right_range);
|
|
||||||
Token::Value op = Next();
|
Token::Value op = Next();
|
||||||
int pos = position();
|
int pos = position();
|
||||||
|
|
||||||
const bool is_right_associative = op == Token::EXP;
|
const bool is_right_associative = op == Token::EXP;
|
||||||
const int next_prec = is_right_associative ? prec1 : prec1 + 1;
|
const int next_prec = is_right_associative ? prec1 : prec1 + 1;
|
||||||
ExpressionT y = ParseBinaryExpression(next_prec, accept_IN, CHECK_OK);
|
ExpressionT y = ParseBinaryExpression(next_prec, accept_IN, CHECK_OK);
|
||||||
right_range_scope.Finalize();
|
|
||||||
impl()->RewriteNonPattern(CHECK_OK);
|
impl()->RewriteNonPattern(CHECK_OK);
|
||||||
|
|
||||||
if (impl()->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos)) {
|
if (impl()->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (op == Token::OR || op == Token::AND) {
|
|
||||||
impl()->RecordExpressionSourceRange(y, right_range);
|
|
||||||
}
|
|
||||||
|
|
||||||
// For now we distinguish between comparisons and other binary
|
// For now we distinguish between comparisons and other binary
|
||||||
// operations. (We could combine the two and get rid of this
|
// operations. (We could combine the two and get rid of this
|
||||||
// code and AST node eventually.)
|
// code and AST node eventually.)
|
||||||
|
@ -1034,13 +1034,6 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
|
|||||||
new (zone()) ConditionalSourceRanges(then_range, else_range));
|
new (zone()) ConditionalSourceRanges(then_range, else_range));
|
||||||
}
|
}
|
||||||
|
|
||||||
V8_INLINE void RecordExpressionSourceRange(Expression* node,
|
|
||||||
const SourceRange& body_range) {
|
|
||||||
if (source_range_map_ == nullptr) return;
|
|
||||||
source_range_map_->Insert(node,
|
|
||||||
new (zone()) ExpressionSourceRanges(body_range));
|
|
||||||
}
|
|
||||||
|
|
||||||
V8_INLINE void RecordJumpStatementSourceRange(Statement* node,
|
V8_INLINE void RecordJumpStatementSourceRange(Statement* node,
|
||||||
int32_t continuation_position) {
|
int32_t continuation_position) {
|
||||||
if (source_range_map_ == nullptr) return;
|
if (source_range_map_ == nullptr) return;
|
||||||
|
@ -666,142 +666,4 @@ f(); // 0200
|
|||||||
{"start":61,"end":150,"count":1}]
|
{"start":61,"end":150,"count":1}]
|
||||||
);
|
);
|
||||||
|
|
||||||
TestCoverage(
|
|
||||||
"LogicalOrExpression assignment",
|
|
||||||
`
|
|
||||||
const a = true || 99 // 0000
|
|
||||||
function b () { // 0050
|
|
||||||
const b = a || 2 // 0100
|
|
||||||
} // 0150
|
|
||||||
b() // 0200
|
|
||||||
b() // 0250
|
|
||||||
`,
|
|
||||||
[{"start":0,"end":299,"count":1},
|
|
||||||
{"start":15,"end":20,"count":0},
|
|
||||||
{"start":50,"end":151,"count":2},
|
|
||||||
{"start":114,"end":118,"count":0}]);
|
|
||||||
|
|
||||||
TestCoverage(
|
|
||||||
"LogicalOrExpression IsTest()",
|
|
||||||
`
|
|
||||||
true || false // 0000
|
|
||||||
const a = 99 // 0050
|
|
||||||
a || 50 // 0100
|
|
||||||
const b = false // 0150
|
|
||||||
if (b || true) {} // 0200
|
|
||||||
`,
|
|
||||||
[{"start":0,"end":249,"count":1},
|
|
||||||
{"start":5,"end":13,"count":0},
|
|
||||||
{"start":102,"end":107,"count":0}]);
|
|
||||||
|
|
||||||
TestCoverage(
|
|
||||||
"LogicalAndExpression assignment",
|
|
||||||
`
|
|
||||||
const a = false && 99 // 0000
|
|
||||||
function b () { // 0050
|
|
||||||
const b = a && 2 // 0100
|
|
||||||
} // 0150
|
|
||||||
b() // 0200
|
|
||||||
b() // 0250
|
|
||||||
const c = true && 50 // 0300
|
|
||||||
`,
|
|
||||||
[{"start":0,"end":349,"count":1},
|
|
||||||
{"start":16,"end":21,"count":0},
|
|
||||||
{"start":50,"end":151,"count":2},
|
|
||||||
{"start":114,"end":118,"count":0}]);
|
|
||||||
|
|
||||||
TestCoverage(
|
|
||||||
"LogicalAndExpression IsTest()",
|
|
||||||
`
|
|
||||||
false && true // 0000
|
|
||||||
const a = 0 // 0050
|
|
||||||
a && 50 // 0100
|
|
||||||
const b = true // 0150
|
|
||||||
if (b && true) {} // 0200
|
|
||||||
true && true // 0250
|
|
||||||
`,
|
|
||||||
[{"start":0,"end":299,"count":1},
|
|
||||||
{"start":6,"end":13,"count":0},
|
|
||||||
{"start":102,"end":107,"count":0}]);
|
|
||||||
|
|
||||||
TestCoverage(
|
|
||||||
"NaryLogicalOr assignment",
|
|
||||||
`
|
|
||||||
const a = true // 0000
|
|
||||||
const b = false // 0050
|
|
||||||
const c = false || false || 99 // 0100
|
|
||||||
const d = false || true || 99 // 0150
|
|
||||||
const e = true || true || 99 // 0200
|
|
||||||
const f = b || b || 99 // 0250
|
|
||||||
const g = b || a || 99 // 0300
|
|
||||||
const h = a || a || 99 // 0350
|
|
||||||
const i = a || (b || c) || d // 0400
|
|
||||||
`,
|
|
||||||
[{"start":0,"end":449,"count":1},
|
|
||||||
{"start":174,"end":179,"count":0},
|
|
||||||
{"start":215,"end":222,"count":0},
|
|
||||||
{"start":223,"end":228,"count":0},
|
|
||||||
{"start":317,"end":322,"count":0},
|
|
||||||
{"start":362,"end":366,"count":0},
|
|
||||||
{"start":367,"end":372,"count":0},
|
|
||||||
{"start":412,"end":423,"count":0},
|
|
||||||
{"start":424,"end":428,"count":0}]);
|
|
||||||
|
|
||||||
TestCoverage(
|
|
||||||
"NaryLogicalOr IsTest()",
|
|
||||||
`
|
|
||||||
const a = true // 0000
|
|
||||||
const b = false // 0050
|
|
||||||
false || false || 99 // 0100
|
|
||||||
false || true || 99 // 0150
|
|
||||||
true || true || 99 // 0200
|
|
||||||
b || b || 99 // 0250
|
|
||||||
b || a || 99 // 0300
|
|
||||||
a || a || 99 // 0350
|
|
||||||
`,
|
|
||||||
[{"start":0,"end":399,"count":1},
|
|
||||||
{"start":164,"end":169,"count":0},
|
|
||||||
{"start":205,"end":212,"count":0},
|
|
||||||
{"start":213,"end":218,"count":0},
|
|
||||||
{"start":307,"end":312,"count":0},
|
|
||||||
{"start":352,"end":356,"count":0},
|
|
||||||
{"start":357,"end":362,"count":0}]);
|
|
||||||
|
|
||||||
TestCoverage(
|
|
||||||
"NaryLogicalAnd assignment",
|
|
||||||
`
|
|
||||||
const a = true // 0000
|
|
||||||
const b = false // 0050
|
|
||||||
const c = false && false && 99 // 0100
|
|
||||||
const d = false && true && 99 // 0150
|
|
||||||
const e = true && true && 99 // 0200
|
|
||||||
const f = true && false || true // 0250
|
|
||||||
const g = true || false && true // 0300
|
|
||||||
`,
|
|
||||||
[{"start":0,"end":349,"count":1},
|
|
||||||
{"start":116,"end":124,"count":0},
|
|
||||||
{"start":125,"end":130,"count":0},
|
|
||||||
{"start":166,"end":173,"count":0},
|
|
||||||
{"start":174,"end":179,"count":0},
|
|
||||||
{"start":315,"end":331,"count":0}
|
|
||||||
]);
|
|
||||||
|
|
||||||
TestCoverage(
|
|
||||||
"NaryLogicalAnd IsTest()",
|
|
||||||
`
|
|
||||||
const a = true // 0000
|
|
||||||
const b = false // 0050
|
|
||||||
false && false && 99 // 0100
|
|
||||||
false && true && 99 // 0150
|
|
||||||
true && true && 99 // 0200
|
|
||||||
true && false || true // 0250
|
|
||||||
true || false && true // 0300
|
|
||||||
`,
|
|
||||||
[{"start":0,"end":349,"count":1},
|
|
||||||
{"start":106,"end":114,"count":0},
|
|
||||||
{"start":115,"end":120,"count":0},
|
|
||||||
{"start":156,"end":163,"count":0},
|
|
||||||
{"start":164,"end":169,"count":0},
|
|
||||||
{"start":305,"end":321,"count":0}]);
|
|
||||||
|
|
||||||
%DebugToggleBlockCoverage(false);
|
%DebugToggleBlockCoverage(false);
|
||||||
|
Loading…
Reference in New Issue
Block a user