Commit 622c92b8 authored by neis's avatar neis Committed by Commit bot

Correctly set the closing condition in array patterns.

This fixes a bug where the iterable's .return method gets called when it
shouldn't.

R=littledan@chromium.org
BUG=v8:4952
LOG=n

Review-Url: https://codereview.chromium.org/1927073002
Cr-Commit-Position: refs/heads/master@{#35850}
parent 31182fb2
...@@ -546,11 +546,11 @@ void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node, ...@@ -546,11 +546,11 @@ void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node,
// let array = []; // let array = [];
// while (!done) { // while (!done) {
// done = true; // If .next, .done or .value throws, don't close.
// result = IteratorNext(iterator); // result = IteratorNext(iterator);
// if (result.done) { // if (!result.done) {
// done = true;
// } else {
// %AppendElement(array, result.value); // %AppendElement(array, result.value);
// done = false;
// } // }
// } // }
...@@ -565,12 +565,6 @@ void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node, ...@@ -565,12 +565,6 @@ void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node,
node->literal_index(), RelocInfo::kNoPosition)); node->literal_index(), RelocInfo::kNoPosition));
} }
// result = IteratorNext(iterator);
Statement* get_next = factory()->NewExpressionStatement(
parser_->BuildIteratorNextResult(factory()->NewVariableProxy(iterator),
result, nopos),
nopos);
// done = true; // done = true;
Statement* set_done = factory()->NewExpressionStatement( Statement* set_done = factory()->NewExpressionStatement(
factory()->NewAssignment( factory()->NewAssignment(
...@@ -578,6 +572,12 @@ void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node, ...@@ -578,6 +572,12 @@ void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node,
factory()->NewBooleanLiteral(true, nopos), nopos), factory()->NewBooleanLiteral(true, nopos), nopos),
nopos); nopos);
// result = IteratorNext(iterator);
Statement* get_next = factory()->NewExpressionStatement(
parser_->BuildIteratorNextResult(factory()->NewVariableProxy(iterator),
result, nopos),
nopos);
// %AppendElement(array, result.value); // %AppendElement(array, result.value);
Statement* append_element; Statement* append_element;
{ {
...@@ -594,29 +594,44 @@ void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node, ...@@ -594,29 +594,44 @@ void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node,
nopos); nopos);
} }
// if (result.done) { #set_done } else { #append_element } // done = false;
Statement* set_done_or_append; Statement* unset_done = factory()->NewExpressionStatement(
factory()->NewAssignment(
Token::ASSIGN, factory()->NewVariableProxy(done),
factory()->NewBooleanLiteral(false, nopos), nopos),
nopos);
// if (!result.done) { #append_element; #unset_done }
Statement* maybe_append_and_unset_done;
{ {
Expression* result_done = Expression* result_done =
factory()->NewProperty(factory()->NewVariableProxy(result), factory()->NewProperty(factory()->NewVariableProxy(result),
factory()->NewStringLiteral( factory()->NewStringLiteral(
ast_value_factory()->done_string(), nopos), ast_value_factory()->done_string(), nopos),
nopos); nopos);
set_done_or_append = factory()->NewIfStatement(result_done, set_done,
append_element, nopos); Block* then = factory()->NewBlock(nullptr, 2, true, nopos);
then->statements()->Add(append_element, zone());
then->statements()->Add(unset_done, zone());
maybe_append_and_unset_done = factory()->NewIfStatement(
factory()->NewUnaryOperation(Token::NOT, result_done, nopos), then,
factory()->NewEmptyStatement(nopos), nopos);
} }
// while (!done) { // while (!done) {
// #set_done;
// #get_next; // #get_next;
// #set_done_or_append; // #maybe_append_and_unset_done;
// } // }
WhileStatement* loop = factory()->NewWhileStatement(nullptr, nopos); WhileStatement* loop = factory()->NewWhileStatement(nullptr, nopos);
{ {
Expression* condition = factory()->NewUnaryOperation( Expression* condition = factory()->NewUnaryOperation(
Token::NOT, factory()->NewVariableProxy(done), nopos); Token::NOT, factory()->NewVariableProxy(done), nopos);
Block* body = factory()->NewBlock(nullptr, 2, true, nopos); Block* body = factory()->NewBlock(nullptr, 3, true, nopos);
body->statements()->Add(set_done, zone());
body->statements()->Add(get_next, zone()); body->statements()->Add(get_next, zone());
body->statements()->Add(set_done_or_append, zone()); body->statements()->Add(maybe_append_and_unset_done, zone());
loop->Initialize(condition, body); loop->Initialize(condition, body);
} }
......
...@@ -1007,6 +1007,26 @@ function* g() { yield 42; return 88 }; ...@@ -1007,6 +1007,26 @@ function* g() { yield 42; return 88 };
assertThrowsEquals(() => { assertThrowsEquals(() => {
(([x]) => x)(g()); (([x]) => x)(g());
}, 666); }, 666);
assertThrowsEquals(() => {
var [...x] = g();
}, 666);
assertThrowsEquals(() => {
let [...x] = g();
}, 666);
assertThrowsEquals(() => {
const [...x] = g();
}, 666);
assertThrowsEquals(() => {
[...x] = g();
}, 666);
assertThrowsEquals(() => {
(([...x]) => x)(g());
}, 666);
} }
...@@ -1051,6 +1071,26 @@ function* g() { yield 42; return 88 }; ...@@ -1051,6 +1071,26 @@ function* g() { yield 42; return 88 };
assertThrowsEquals(() => { assertThrowsEquals(() => {
(([x]) => x)(g()); (([x]) => x)(g());
}, 666); }, 666);
assertThrowsEquals(() => {
var [...x] = g();
}, 666);
assertThrowsEquals(() => {
let [...x] = g();
}, 666);
assertThrowsEquals(() => {
const [...x] = g();
}, 666);
assertThrowsEquals(() => {
[...x] = g();
}, 666);
assertThrowsEquals(() => {
(([...x]) => x)(g());
}, 666);
} }
...@@ -1095,6 +1135,26 @@ function* g() { yield 42; return 88 }; ...@@ -1095,6 +1135,26 @@ function* g() { yield 42; return 88 };
assertThrowsEquals(() => { assertThrowsEquals(() => {
(([x]) => x)(g()); (([x]) => x)(g());
}, 666); }, 666);
assertThrowsEquals(() => {
var [...x] = g();
}, 666);
assertThrowsEquals(() => {
let [...x] = g();
}, 666);
assertThrowsEquals(() => {
const [...x] = g();
}, 666);
assertThrowsEquals(() => {
[...x] = g();
}, 666);
assertThrowsEquals(() => {
(([...x]) => x)(g());
}, 666);
} }
......
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